diff options
author | Wing Lam <lamwing@google.com> | 2013-08-20 16:38:23 -0700 |
---|---|---|
committer | Wing Lam <lamwing@google.com> | 2013-08-21 11:09:36 -0700 |
commit | c4986e7a0c8022817df8f6dabbab4e8a87bd0477 (patch) | |
tree | ba80b3f6c7fb5c15e6c44769790967fccf4462e2 | |
parent | 263c42c75f782fae79f029287b5cf3e12c19039e (diff) | |
download | build-c4986e7a0c8022817df8f6dabbab4e8a87bd0477.tar.gz |
ProGuard support for libraries.
Change-Id: I38069666a4cc9f84c07337f26bd6dcdb0b253548
69 files changed, 948 insertions, 103 deletions
@@ -15,6 +15,8 @@ tests/3rdPartyTests/*/build tests/dependencies/jarProject/build tests/flavorlib/*/build tests/flavorlibWithFailedTests/*/build +tests/libProguardJarDep/*/build +tests/libProguardLibDep/*/build tests/libsTest/*/build tests/multiproject/*/build tests/localJars/*/build 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 ff3efcc..fbf6eb4 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 @@ -40,4 +40,12 @@ public interface BaseConfig { */ @NonNull List<File> getProguardFiles(); + + /** + * Returns the list of proguard rule files for consumers of the library to use. + * + * @return a non-null list of files. + */ + @NonNull + List<File> getConsumerProguardFiles(); } diff --git a/builder/src/main/java/com/android/builder/AndroidBuilder.java b/builder/src/main/java/com/android/builder/AndroidBuilder.java index 9442f4d..34c0dd4 100644 --- a/builder/src/main/java/com/android/builder/AndroidBuilder.java +++ b/builder/src/main/java/com/android/builder/AndroidBuilder.java @@ -564,14 +564,14 @@ public class AndroidBuilder { command.add(sourceOutputDir); } - if (type != VariantConfiguration.Type.LIBRARY && resPackageOutput != null) { + if (resPackageOutput != null) { command.add("-F"); command.add(resPackageOutput); + } - if (proguardOutput != null) { - command.add("-G"); - command.add(proguardOutput); - } + if (proguardOutput != null) { + command.add("-G"); + command.add(proguardOutput); } // options controlled by build variants diff --git a/builder/src/main/java/com/android/builder/DefaultBuildType.java b/builder/src/main/java/com/android/builder/DefaultBuildType.java index ea82e12..5ebbd0b 100644 --- a/builder/src/main/java/com/android/builder/DefaultBuildType.java +++ b/builder/src/main/java/com/android/builder/DefaultBuildType.java @@ -111,7 +111,8 @@ public class DefaultBuildType extends BaseConfigImpl implements BuildType { } @Override - @Nullable public String getPackageNameSuffix() { + @Nullable + public String getPackageNameSuffix() { return mPackageNameSuffix; } @@ -122,7 +123,8 @@ public class DefaultBuildType extends BaseConfigImpl implements BuildType { } @Override - @Nullable public String getVersionNameSuffix() { + @Nullable + public String getVersionNameSuffix() { return mVersionNameSuffix; } diff --git a/builder/src/main/java/com/android/builder/VariantConfiguration.java b/builder/src/main/java/com/android/builder/VariantConfiguration.java index 614d467..5b1b5e5 100644 --- a/builder/src/main/java/com/android/builder/VariantConfiguration.java +++ b/builder/src/main/java/com/android/builder/VariantConfiguration.java @@ -885,6 +885,21 @@ public class VariantConfiguration implements TestData { return fullList; } + @NonNull + public List<Object> getConsumerProguardFiles() { + List<Object> fullList = Lists.newArrayList(); + + // add the config files from the build type, main config and flavors + fullList.addAll(mDefaultConfig.getConsumerProguardFiles()); + fullList.addAll(mBuildType.getConsumerProguardFiles()); + + for (DefaultProductFlavor flavor : mFlavorConfigs) { + fullList.addAll(flavor.getConsumerProguardFiles()); + } + + return fullList; + } + protected void validate() { if (mType != Type.TEST) { File manifest = mDefaultSourceProvider.getManifestFile(); diff --git a/builder/src/main/java/com/android/builder/internal/BaseConfigImpl.java b/builder/src/main/java/com/android/builder/internal/BaseConfigImpl.java index e2517c5..044420b 100644 --- a/builder/src/main/java/com/android/builder/internal/BaseConfigImpl.java +++ b/builder/src/main/java/com/android/builder/internal/BaseConfigImpl.java @@ -33,6 +33,7 @@ public class BaseConfigImpl implements Serializable, BaseConfig { private final List<String> mBuildConfigLines = Lists.newArrayList(); private final List<File> mProguardFiles = Lists.newArrayList(); + private final List<File> mConsumerProguardFiles = Lists.newArrayList(); public void setBuildConfig(String... lines) { mBuildConfigLines.clear(); @@ -56,12 +57,21 @@ public class BaseConfigImpl implements Serializable, BaseConfig { return mProguardFiles; } + @Override + @NonNull + public List<File> getConsumerProguardFiles() { + return mConsumerProguardFiles; + } + protected void _initWith(BaseConfig that) { mBuildConfigLines.clear(); mBuildConfigLines.addAll(that.getBuildConfig()); mProguardFiles.clear(); mProguardFiles.addAll(that.getProguardFiles()); + + mConsumerProguardFiles.clear(); + mConsumerProguardFiles.addAll(that.getConsumerProguardFiles()); } @Override @@ -73,6 +83,7 @@ public class BaseConfigImpl implements Serializable, BaseConfig { if (!mBuildConfigLines.equals(that.mBuildConfigLines)) return false; if (!mProguardFiles.equals(that.mProguardFiles)) return false; + if (!mConsumerProguardFiles.equals(that.mConsumerProguardFiles)) return false; return true; } @@ -81,6 +92,7 @@ public class BaseConfigImpl implements Serializable, BaseConfig { public int hashCode() { int result = mBuildConfigLines.hashCode(); result = 31 * result + mProguardFiles.hashCode(); + result = 31 * result + mConsumerProguardFiles.hashCode(); return result; } } diff --git a/gradle/build.gradle b/gradle/build.gradle index 16b99e6..89d1d47 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -29,7 +29,7 @@ dependencies { groovy localGroovy() compile project(':builder') - runtime 'net.sf.proguard:proguard-gradle:4.9' + compile 'net.sf.proguard:proguard-gradle:4.9' testCompile 'junit:junit:3.8.1' diff --git a/gradle/src/build-test/groovy/com/android/build/gradle/AutomatedBuildTest.java b/gradle/src/build-test/groovy/com/android/build/gradle/AutomatedBuildTest.java index b92239f..c2b1e0c 100644 --- a/gradle/src/build-test/groovy/com/android/build/gradle/AutomatedBuildTest.java +++ b/gradle/src/build-test/groovy/com/android/build/gradle/AutomatedBuildTest.java @@ -35,10 +35,11 @@ public class AutomatedBuildTest extends BuildTest { private static final String[] sBuiltProjects = new String[] { "aidl", "api", "applibtest", "assets", "attrOrder", "basic", "dependencies", - "dependencyChecker", "flavored", "flavorlib", "flavors", "libTestDep", "libsTest", - "localJars", "migrated", "multiproject", "multires", "overlay1", "overlay2", - "pkgOverride", "proguard", "proguardLib", "renderscript", "renderscriptInLib", - "renderscriptMultiSrc", "sameNamedLibs", "tictactoe" /*, "autorepo"*/ + "dependencyChecker", "flavored", "flavorlib", "flavors", "libProguardJarDep", + "libProguardLibDep", "libTestDep", "libsTest", "localJars", "migrated", "multiproject", + "multires", "overlay1", "overlay2", "pkgOverride", "proguard", "proguardLib", + "renderscript", "renderscriptInLib", "renderscriptMultiSrc", "sameNamedLibs", + "tictactoe" /*, "autorepo"*/ }; private static final String[] sReportProjects = new String[] { 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 0ccfc24..af0bd32 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 @@ -16,10 +16,13 @@ package com.android.build.gradle; -import javax.imageio.ImageIO; +import com.google.common.base.Charsets; +import com.google.common.io.Files; + import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import javax.imageio.ImageIO; /** * Some manual tests for building projects. @@ -67,6 +70,29 @@ public class ManualBuildTest extends BuildTest { } } + // test whether a library project has its fields ProGuarded + public void testLibProguard() throws Exception { + File project = new File(testDir, "libProguard"); + File fileOutput = new File(project, "build/proguard/release"); + + runGradleTasks(sdkDir, BasePlugin.GRADLE_MIN_VERSION, + project, "clean", "build"); + checkFile(fileOutput, "mapping.txt", new String[]{"int proguardInt -> a"}); + + } + + // test whether proguard.txt has been correctly merged + public void testLibProguardConsumerFile() throws Exception { + File project = new File(testDir, "libProguardConsumerFiles"); + File debugFileOutput = new File(project, "build/bundles/debug"); + File releaseFileOutput = new File(project, "build/bundles/release"); + + runGradleTasks(sdkDir, BasePlugin.GRADLE_MIN_VERSION, + project, "clean", "build"); + checkFile(debugFileOutput, "proguard.txt", new String[]{"A"}); + checkFile(releaseFileOutput, "proguard.txt", new String[]{"A", "B", "C"}); + } + public void test3rdPartyTests() throws Exception { // custom because we want to run deviceCheck even without devices, since we use // a fake DeviceProvider that doesn't use a device, but only record the calls made @@ -86,4 +112,16 @@ public class ManualBuildTest extends BuildTest { expectedColor, rgb, f), expectedColor, rgb); } + + private static void checkFile(File folder, String fileName, String[] expectedContents) + throws IOException { + File f = new File(folder, fileName); + assertTrue("File '" + f.getAbsolutePath() + "' does not exist.", f.isFile()); + + String contents = Files.toString(f, Charsets.UTF_8); + for (String expectedContent : expectedContents) { + assertTrue("File '" + f.getAbsolutePath() + "' does not contain: " + expectedContent, + contents.contains(expectedContent)); + } + } } diff --git a/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java b/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java index 93b53b6..388aef9 100644 --- a/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java +++ b/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java @@ -39,8 +39,9 @@ public class DeviceTest extends BuildTest { private static final String[] sBuiltProjects = new String[] { "api", "assets", "applibtest", "attrOrder", "basic", "dependencies", "flavored", - "flavorlib", "flavors", "libTestDep", "libsTest", "migrated", "multires", "overlay1", - "overlay2", "pkgOverride", "proguard", "proguardLib", "sameNamedLibs" + "flavorlib", "flavors", "libProguardJarDep", "libProguardLibDep", "libTestDep", "libsTest", + "migrated", "multires", "overlay1", "overlay2", "pkgOverride", "proguard", "proguardLib", + "sameNamedLibs" }; public static Test suite() { 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 e85c784..4e30a74 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy @@ -118,6 +118,8 @@ import static com.android.builder.BuilderConstants.INSTRUMENT_TEST * Base class for all Android plugins */ public abstract class BasePlugin { + protected final static String DIR_BUNDLES = "bundles"; + public static final String GRADLE_MIN_VERSION = "1.6" public static final String[] GRADLE_SUPPORTED_VERSIONS = [ GRADLE_MIN_VERSION, "1.7" ] @@ -968,55 +970,11 @@ public abstract class BasePlugin { Closure proguardFileClosure = { } if (!(variantData instanceof TestVariantData) && variantConfig.buildType.runProguard) { - - def proguardTask = project.tasks.create("proguard${variantData.name}", ProGuardTask); - proguardTask.dependsOn variantData.javaCompileTask - variantData.proguardTask = proguardTask - - File outFile = project.file( - "${project.buildDir}/classes-proguard/${variantData.dirName}/classes.jar") - libraryClosure = { Collections.emptyList() } sourceClosure = { Collections.emptyList() } - proguardFileClosure = { outFile } - - // because the Proguard task acts on all the config right away and not when the - // task actually runs, let's configure it in its doFirst - - proguardTask.doFirst { - - // all the config files coming from build type, product flavors. - List<Object> proguardFiles = variantConfig.getProguardFiles(true /*includeLibs*/); - for (Object proguardFile : proguardFiles) { - proguardTask.configuration(proguardFile) - } - - // also the config file output by aapt - proguardTask.configuration(variantData.processResourcesTask.proguardOutputFile) - - // injar: the compilation output - proguardTask.injars(variantData.javaCompileTask.destinationDir) - - // injar: the dependencies - for (File inJar : variantConfig.packagedJars) { - proguardTask.injars(inJar, filter: '!META-INF/MANIFEST.MF') - } - // libraryJars: the runtime jars - for (String runtimeJar : getRuntimeJarList()) { - proguardTask.libraryjars(runtimeJar) - } - - proguardTask.outjars(outFile) - - proguardTask.dump("${project.buildDir}/proguard/${variantData.dirName}/dump.txt") - proguardTask.printseeds( - "${project.buildDir}/proguard/${variantData.dirName}/seeds.txt") - proguardTask.printusage( - "${project.buildDir}/proguard/${variantData.dirName}/usage.txt") - proguardTask.printmapping( - "${project.buildDir}/proguard/${variantData.dirName}/mapping.txt") - } + File outFile = createProguardTasks(variantData, variantConfig) + proguardFileClosure = { outFile } } // Add a dex task @@ -1147,6 +1105,106 @@ public abstract class BasePlugin { uninstallAll.dependsOn uninstallTask } + /** + * Creates the proguarding task for the given Variant. + * @param variantData the variant data. + * @param variantConfig the variant configuration of variantData + * @return outFile file outputted by proguard + */ + @NonNull + protected File createProguardTasks(@NonNull BaseVariantData variantData, + @NonNull VariantConfiguration variantConfig) { + def proguardTask = project.tasks.create("proguard${variantData.name}", ProGuardTask); + proguardTask.dependsOn variantData.javaCompileTask + variantData.proguardTask = proguardTask + + File outFile; + if (variantData instanceof LibraryVariantData) { + outFile = project.file( + "${project.buildDir}/$DIR_BUNDLES/${variantData.dirName}/classes.jar") + } else { + outFile = project.file( + "${project.buildDir}/classes-proguard/${variantData.dirName}/classes.jar") + } + + // because the Proguard task acts on all the config right away and not when the + // task actually runs, let's configure it in its doFirst + proguardTask.doFirst { + // all the config files coming from build type, product flavors. + List<Object> proguardFiles = variantConfig.getProguardFiles(true /*includeLibs*/); + for (Object proguardFile : proguardFiles) { + proguardTask.configuration(proguardFile) + } + + // also the config file output by aapt + proguardTask.configuration(variantData.processResourcesTask.proguardOutputFile) + + if (variantData instanceof LibraryVariantData) { + String packageName = variantConfig.getPackageFromManifest() + if (packageName == null) { + throw new BuildException("Failed to read manifest", null) + } + packageName = packageName.replace('.', '/'); + + // injar: the compilation output + // exclude R files and such from output + String exclude = '!' + packageName + "/R.class" + exclude += (', !' + packageName + "/R\$*.class") + exclude += (', !' + packageName + "/Manifest.class") + exclude += (', !' + packageName + "/Manifest\$*.class") + exclude += (', !' + packageName + "/BuildConfig.class") + proguardTask.injars(variantData.javaCompileTask.destinationDir, filter: exclude) + + // include R files and such for compilation + String include = exclude.replace('!', '') + proguardTask.libraryjars(variantData.javaCompileTask.destinationDir, filter: include) + + List<File> packagedJars = variantConfig.packagedJars + + // injar: the local dependencies, filter out local jars from packagedJars + Object[] jars = LibraryPlugin.getLocalJarFileList(variantData.variantDependency) + for (Object inJar : jars) { + if (packagedJars.contains(inJar)) { + packagedJars.remove(inJar); + } + proguardTask.injars((File) inJar, filter: '!META-INF/MANIFEST.MF') + } + + // libjar: the library dependencies + for (File libJar : packagedJars) { + proguardTask.libraryjars(libJar, filter: '!META-INF/MANIFEST.MF') + } + + // ensure local jars keep their package names + proguardTask.keeppackagenames() + } else { + // injar: the compilation output + proguardTask.injars(variantData.javaCompileTask.destinationDir) + + // injar: the dependencies + for (File inJar : variantConfig.packagedJars) { + proguardTask.injars(inJar, filter: '!META-INF/MANIFEST.MF') + } + } + + // libraryJars: the runtime jars + for (String runtimeJar : getRuntimeJarList()) { + proguardTask.libraryjars(runtimeJar) + } + + proguardTask.outjars(outFile) + + proguardTask.dump("${project.buildDir}/proguard/${variantData.dirName}/dump.txt") + proguardTask.printseeds( + "${project.buildDir}/proguard/${variantData.dirName}/seeds.txt") + proguardTask.printusage( + "${project.buildDir}/proguard/${variantData.dirName}/usage.txt") + proguardTask.printmapping( + "${project.buildDir}/proguard/${variantData.dirName}/mapping.txt") + } + return outFile + } + private void createReportTasks() { def dependencyReportTask = project.tasks.create("androidDependencies", DependencyReportTask) dependencyReportTask.setDescription("Displays the Android dependencies of the project") diff --git a/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy index 93420e8..750d23f 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy @@ -58,8 +58,6 @@ import javax.inject.Inject */ public class LibraryPlugin extends BasePlugin implements Plugin<Project> { - private final static String DIR_BUNDLES = "bundles"; - LibraryExtension extension BuildTypeData debugBuildTypeData BuildTypeData releaseBuildTypeData @@ -185,11 +183,6 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> { VariantConfiguration variantConfig = variantData.variantConfiguration DefaultBuildType buildType = variantConfig.buildType - String packageName = variantConfig.getPackageFromManifest() - if (packageName == null) { - throw new BuildException("Failed to read manifest", null) - } - createPrepareDependenciesTask(variantData) // Add a task to process the manifest(s) @@ -230,21 +223,6 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> { // Add a compile task createCompileTask(variantData, null/*testedVariant*/) - // jar the classes. - Jar jar = project.tasks.create("package${buildType.name.capitalize()}Jar", Jar); - jar.dependsOn variantData.javaCompileTask, variantData.processJavaResources - jar.from(variantData.javaCompileTask.outputs); - jar.from(variantData.processJavaResources.destinationDir) - - jar.destinationDir = project.file("$project.buildDir/$DIR_BUNDLES/${variantData.dirName}") - jar.archiveName = "classes.jar" - packageName = packageName.replace('.', '/'); - jar.exclude(packageName + "/R.class") - jar.exclude(packageName + "/R\$*.class") - jar.exclude(packageName + "/Manifest.class") - jar.exclude(packageName + "/Manifest\$*.class") - jar.exclude(packageName + "/BuildConfig.class") - // package the aidl files into the bundle folder Sync packageAidl = project.tasks.create("package${variantData.name}Aidl", Sync) // packageAidl from 3 sources. the order is important to make sure the override works well. @@ -260,24 +238,57 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> { packageRenderscript.into(project.file( "$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/$SdkConstants.FD_RENDERSCRIPT")) - // package the renderscript header files files into the bundle folder - Sync packageLocalJar = project.tasks.create("package${variantData.name}LocalJar", Sync) - packageLocalJar.from(getLocalJarFileList(variantData.variantDependency)) - packageLocalJar.into(project.file( - "$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/$SdkConstants.LIBS_FOLDER")) - - // merge the proguard files together + // merge consumer proguard files from different build types and flavors MergeFileTask mergeFileTask = project.tasks.create("merge${variantData.name}ProguardFiles", MergeFileTask) mergeFileTask.conventionMapping.inputFiles = { - project.files(variantConfig.getProguardFiles(false)).files } + project.files(variantConfig.getConsumerProguardFiles()).files } mergeFileTask.conventionMapping.outputFile = { project.file( "$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/$LibraryBundle.FN_PROGUARD_TXT") } Zip bundle = project.tasks.create("bundle${variantData.name}", Zip) - bundle.dependsOn packageRes, jar, packageAidl, packageRenderscript, packageLocalJar, mergeFileTask + + if (variantConfig.buildType.runProguard) { + // run proguard on output of compile task + createProguardTasks(variantData, variantConfig) + + // hack since bundle can't depend on variantData.proguardTask + mergeFileTask.dependsOn variantData.proguardTask + + bundle.dependsOn packageRes, packageAidl, packageRenderscript, mergeFileTask + } else { + Sync packageLocalJar = project.tasks.create("package${variantData.name}LocalJar", Sync) + packageLocalJar.from(getLocalJarFileList(variantData.variantDependency)) + packageLocalJar.into(project.file( + "$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/$SdkConstants.LIBS_FOLDER")) + + // jar the classes. + Jar jar = project.tasks.create("package${buildType.name.capitalize()}Jar", Jar); + jar.dependsOn variantData.javaCompileTask, variantData.processJavaResources + jar.from(variantData.javaCompileTask.outputs); + jar.from(variantData.processJavaResources.destinationDir) + + jar.destinationDir = project.file("$project.buildDir/$DIR_BUNDLES/${variantData.dirName}") + jar.archiveName = "classes.jar" + + String packageName = variantConfig.getPackageFromManifest() + if (packageName == null) { + throw new BuildException("Failed to read manifest", null) + } + packageName = packageName.replace('.', '/'); + + jar.exclude(packageName + "/R.class") + jar.exclude(packageName + "/R\$*.class") + jar.exclude(packageName + "/Manifest.class") + jar.exclude(packageName + "/Manifest\$*.class") + jar.exclude(packageName + "/BuildConfig.class") + + bundle.dependsOn packageRes, jar, packageAidl, packageRenderscript, packageLocalJar, + mergeFileTask + } + bundle.setDescription("Assembles a bundle containing the library in ${variantData.name}."); bundle.destinationDir = project.file("$project.buildDir/libs") bundle.extension = BuilderConstants.EXT_LIB_ARCHIVE 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 6c4f97f..e8fa660 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 @@ -86,4 +86,19 @@ public class BuildTypeDsl extends DefaultBuildType implements Serializable { } return this; } + + @NonNull + public BuildTypeDsl consumerProguardFiles(Object... proguardFileArray) { + consumerProguardFiles.addAll(fileResolver.resolveFiles(proguardFileArray).files); + return this; + } + + @NonNull + public BuildTypeDsl setConsumerProguardFiles(Iterable<?> proguardFileIterable) { + consumerProguardFiles.clear(); + for (Object proguardFile : proguardFileIterable) { + consumerProguardFiles.add(fileResolver.resolve(proguardFile)); + } + return this; + } } 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 91a27b1..4ae05cb 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 @@ -63,4 +63,19 @@ class ProductFlavorDsl extends DefaultProductFlavor { } return this; } + + @NonNull + public ProductFlavorDsl consumerProguardFiles(Object... proguardFileArray) { + consumerProguardFiles.addAll(fileResolver.resolveFiles(proguardFileArray).files); + return this; + } + + @NonNull + public ProductFlavorDsl setconsumerProguardFiles(Iterable<?> proguardFileIterable) { + consumerProguardFiles.clear(); + for (Object proguardFile : proguardFileIterable) { + consumerProguardFiles.add(fileResolver.resolve(proguardFile)); + } + return this; + } } 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 f5fa46c..11b387d 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 @@ -115,8 +115,15 @@ class BuildTypeImpl implements BuildType, Serializable { return Collections.emptyList(); } + @NonNull + @Override + public List<File> getProguardFiles() { + return Collections.emptyList(); + } + + @NonNull @Override - public @NonNull List<File> getProguardFiles() { + public List<File> getConsumerProguardFiles() { return Collections.emptyList(); } } 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 db4cb6b..0e3be19 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 @@ -142,4 +142,10 @@ class ProductFlavorImpl implements ProductFlavor, Serializable { public List<File> getProguardFiles() { return Collections.emptyList(); } + + @NonNull + @Override + public List<File> getConsumerProguardFiles() { + return Collections.emptyList(); + } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApkVariantData.java b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApkVariantData.java index 822cdfe..ef74235 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApkVariantData.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApkVariantData.java @@ -21,14 +21,12 @@ import com.android.build.gradle.tasks.PackageApplication; import com.android.build.gradle.tasks.ZipAlign; import com.android.builder.VariantConfiguration; import org.gradle.api.DefaultTask; -import proguard.gradle.ProGuardTask; /** * Base data about a variant that generates an APK file. */ public abstract class ApkVariantData extends BaseVariantData { - public ProGuardTask proguardTask; public Dex dexTask; public PackageApplication packageApplicationTask; public ZipAlign zipAlignTask; diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApplicationVariantData.java b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApplicationVariantData.java index 0f8d4ed..a602a29 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApplicationVariantData.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApplicationVariantData.java @@ -41,11 +41,6 @@ public class ApplicationVariantData extends ApkVariantData implements TestedVari } @Override - public boolean getRunProguard() { - return getVariantConfiguration().getBuildType().isRunProguard(); - } - - @Override public void setTestVariantData(@Nullable TestVariantData testVariantData) { this.testVariantData = testVariantData; } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantData.java b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantData.java index 135eeaf..f69a1d4 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantData.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantData.java @@ -34,6 +34,7 @@ import groovy.lang.Closure; import org.gradle.api.Task; import org.gradle.api.tasks.Copy; import org.gradle.api.tasks.compile.JavaCompile; +import proguard.gradle.ProGuardTask; import java.io.File; @@ -57,6 +58,7 @@ public abstract class BaseVariantData { public GenerateBuildConfig generateBuildConfigTask; public JavaCompile javaCompileTask; + public ProGuardTask proguardTask; public Copy processJavaResources; private Object outputFile; @@ -139,7 +141,7 @@ public abstract class BaseVariantData { } public boolean getRunProguard() { - return false; + return getVariantConfiguration().getBuildType().isRunProguard(); } public void setOutputFile(Object file) { diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/TestVariantData.java b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/TestVariantData.java index ebd336c..dca2d16 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/TestVariantData.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/TestVariantData.java @@ -87,4 +87,9 @@ public class TestVariantData extends ApkVariantData { public boolean getZipAlign() { return false; } + + @Override + public boolean getRunProguard() { + return false; + } } diff --git a/tests/libProguard/build.gradle b/tests/libProguard/build.gradle new file mode 100644 index 0000000..6a522ee --- /dev/null +++ b/tests/libProguard/build.gradle @@ -0,0 +1,26 @@ +buildscript { + repositories { + maven { url '../../../../out/host/gradle/repo' } + } + dependencies { + classpath 'com.android.tools.build:gradle:0.5.0-SNAPSHOT' + } +} + +apply plugin: 'android-library' + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + defaultConfig { + versionCode 12 + versionName "2.0" + minSdkVersion 16 + targetSdkVersion 16 + proguardFile 'config.pro' + } + release { + runProguard true + } +} diff --git a/tests/libProguard/config.pro b/tests/libProguard/config.pro new file mode 100644 index 0000000..3664f87 --- /dev/null +++ b/tests/libProguard/config.pro @@ -0,0 +1,3 @@ +-keep public class com.android.tests.basic.StringProvider { + public static java.lang.String getString(int); +} diff --git a/tests/libProguard/src/main/AndroidManifest.xml b/tests/libProguard/src/main/AndroidManifest.xml new file mode 100644 index 0000000..593a287 --- /dev/null +++ b/tests/libProguard/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.basic"> +</manifest> diff --git a/tests/libProguard/src/main/java/com/android/tests/basic/StringProvider.java b/tests/libProguard/src/main/java/com/android/tests/basic/StringProvider.java new file mode 100644 index 0000000..18fe927 --- /dev/null +++ b/tests/libProguard/src/main/java/com/android/tests/basic/StringProvider.java @@ -0,0 +1,11 @@ +package com.android.tests.basic; + +import java.lang.Integer; + +public class StringProvider { + private static int proguardInt = 5; + + public static String getString(int foo) { + return Integer.toString(foo + proguardInt); + } +} diff --git a/tests/libProguardConsumerFiles/A.txt b/tests/libProguardConsumerFiles/A.txt new file mode 100644 index 0000000..f70f10e --- /dev/null +++ b/tests/libProguardConsumerFiles/A.txt @@ -0,0 +1 @@ +A diff --git a/tests/libProguardConsumerFiles/B.txt b/tests/libProguardConsumerFiles/B.txt new file mode 100644 index 0000000..223b783 --- /dev/null +++ b/tests/libProguardConsumerFiles/B.txt @@ -0,0 +1 @@ +B diff --git a/tests/libProguardConsumerFiles/C.txt b/tests/libProguardConsumerFiles/C.txt new file mode 100644 index 0000000..3cc58df --- /dev/null +++ b/tests/libProguardConsumerFiles/C.txt @@ -0,0 +1 @@ +C diff --git a/tests/libProguardConsumerFiles/build.gradle b/tests/libProguardConsumerFiles/build.gradle new file mode 100644 index 0000000..fbefef8 --- /dev/null +++ b/tests/libProguardConsumerFiles/build.gradle @@ -0,0 +1,32 @@ +buildscript { + repositories { + maven { url '../../../../out/host/gradle/repo' } + } + dependencies { + classpath 'com.android.tools.build:gradle:0.5.0-SNAPSHOT' + } +} + +apply plugin: 'android-library' + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + defaultConfig { + versionCode 12 + versionName "2.0" + minSdkVersion 16 + targetSdkVersion 16 + proguardFile 'config.pro' + consumerProguardFiles 'A.txt' + } + + debug { + } + + release { + runProguard true + consumerProguardFiles 'B.txt', 'C.txt' + } +} diff --git a/tests/libProguardConsumerFiles/config.pro b/tests/libProguardConsumerFiles/config.pro new file mode 100644 index 0000000..3664f87 --- /dev/null +++ b/tests/libProguardConsumerFiles/config.pro @@ -0,0 +1,3 @@ +-keep public class com.android.tests.basic.StringProvider { + public static java.lang.String getString(int); +} diff --git a/tests/libProguardConsumerFiles/src/main/AndroidManifest.xml b/tests/libProguardConsumerFiles/src/main/AndroidManifest.xml new file mode 100644 index 0000000..593a287 --- /dev/null +++ b/tests/libProguardConsumerFiles/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.basic"> +</manifest> diff --git a/tests/libProguardConsumerFiles/src/main/java/com/android/tests/basic/StringProvider.java b/tests/libProguardConsumerFiles/src/main/java/com/android/tests/basic/StringProvider.java new file mode 100644 index 0000000..18fe927 --- /dev/null +++ b/tests/libProguardConsumerFiles/src/main/java/com/android/tests/basic/StringProvider.java @@ -0,0 +1,11 @@ +package com.android.tests.basic; + +import java.lang.Integer; + +public class StringProvider { + private static int proguardInt = 5; + + public static String getString(int foo) { + return Integer.toString(foo + proguardInt); + } +} diff --git a/tests/libProguardJarDep/app/build.gradle b/tests/libProguardJarDep/app/build.gradle new file mode 100644 index 0000000..8166bf8 --- /dev/null +++ b/tests/libProguardJarDep/app/build.gradle @@ -0,0 +1,35 @@ +apply plugin: 'android' + +repositories { + mavenCentral() +} + +dependencies { + compile project(':lib') +} + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + testBuildType "proguard" + + defaultConfig { + versionCode 12 + versionName "2.0" + minSdkVersion 16 + targetSdkVersion 16 + } + + buildTypes { + proguard.initWith(buildTypes.debug) + proguard { + runProguard true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'config.pro' + } + } + + dexOptions { + incremental false + } +} diff --git a/tests/libProguardJarDep/app/config.pro b/tests/libProguardJarDep/app/config.pro new file mode 100644 index 0000000..4321975 --- /dev/null +++ b/tests/libProguardJarDep/app/config.pro @@ -0,0 +1,2 @@ +-keep class com.google.** +-dontwarn com.google.** diff --git a/tests/libProguardJarDep/app/src/instrumentTest/java/com/android/tests/basic/MainTest.java b/tests/libProguardJarDep/app/src/instrumentTest/java/com/android/tests/basic/MainTest.java new file mode 100644 index 0000000..6b3ff36 --- /dev/null +++ b/tests/libProguardJarDep/app/src/instrumentTest/java/com/android/tests/basic/MainTest.java @@ -0,0 +1,42 @@ +package com.android.tests.basic; + +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.MediumTest; +import android.widget.TextView; + +public class MainTest extends ActivityInstrumentationTestCase2<Main> { + + private TextView mTextView; + + /** + * 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); + mTextView = (TextView) a.findViewById(R.id.dateText); + } + + /** + * 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(mTextView); + } + + public void testTextViewContent() { + assertEquals("FredBarney", mTextView.getText()); + } +} + diff --git a/tests/libProguardJarDep/app/src/main/AndroidManifest.xml b/tests/libProguardJarDep/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..4f8d570 --- /dev/null +++ b/tests/libProguardJarDep/app/src/main/AndroidManifest.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.basic"> + <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> + + <uses-permission android:name="com.blah" /> + + <permission-group android:name="foo.permission-group.COST_MONEY" + android:label="@string/app_name" + android:description="@string/app_name" /> + + <permission android:name="foo.permission.SEND_SMS" + android:permissionGroup="foo.permission-group.COST_MONEY" + android:label="@string/app_name" + android:description="@string/app_name" /> + + <permission android:name="foo.blah.SEND_SMS" + android:permissionGroup="foo.permission-group.COST_MONEY" + android:label="@string/app_name" + android:description="@string/app_name" /> + +</manifest> diff --git a/tests/libProguardJarDep/app/src/main/java/com/android/tests/basic/Main.java b/tests/libProguardJarDep/app/src/main/java/com/android/tests/basic/Main.java new file mode 100644 index 0000000..f5a6953 --- /dev/null +++ b/tests/libProguardJarDep/app/src/main/java/com/android/tests/basic/Main.java @@ -0,0 +1,31 @@ +package com.android.tests.basic; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.TextView; +import java.lang.reflect.Method; + +public class Main extends Activity +{ + + private int foo = 1234; + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + TextView tv = (TextView) findViewById(R.id.dateText); + + try { + // use reflection to make sure the class wasn't obfuscated + Class<?> theClass = Class.forName("com.android.tests.basic.StringGetter"); + Method method = theClass.getDeclaredMethod("getString"); + tv.setText((String) method.invoke(null)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/tests/libProguardJarDep/app/src/main/res/drawable/icon.png b/tests/libProguardJarDep/app/src/main/res/drawable/icon.png Binary files differnew file mode 100644 index 0000000..a07c69f --- /dev/null +++ b/tests/libProguardJarDep/app/src/main/res/drawable/icon.png diff --git a/tests/libProguardJarDep/app/src/main/res/layout/main.xml b/tests/libProguardJarDep/app/src/main/res/layout/main.xml new file mode 100644 index 0000000..89ab091 --- /dev/null +++ b/tests/libProguardJarDep/app/src/main/res/layout/main.xml @@ -0,0 +1,20 @@ +<?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 - Basic" + android:id="@+id/text" + /> +<TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="" + android:id="@+id/dateText" + /> +</LinearLayout> + diff --git a/tests/libProguardJarDep/app/src/main/res/values/strings.xml b/tests/libProguardJarDep/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..60ea2d0 --- /dev/null +++ b/tests/libProguardJarDep/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">_Test-Basic</string> +</resources> diff --git a/tests/libProguardJarDep/build.gradle b/tests/libProguardJarDep/build.gradle new file mode 100644 index 0000000..62a4405 --- /dev/null +++ b/tests/libProguardJarDep/build.gradle @@ -0,0 +1,8 @@ +buildscript { + repositories { + maven { url '../../../../out/host/gradle/repo' } + } + dependencies { + classpath 'com.android.tools.build:gradle:0.5.0-SNAPSHOT' + } +} diff --git a/tests/libProguardJarDep/lib/build.gradle b/tests/libProguardJarDep/lib/build.gradle new file mode 100644 index 0000000..40cb840 --- /dev/null +++ b/tests/libProguardJarDep/lib/build.gradle @@ -0,0 +1,30 @@ +apply plugin: 'android-library' + +repositories { + mavenCentral() +} + +dependencies { + compile 'com.google.guava:guava:11.0.2' + compile fileTree(dir: 'libs', include: '*.jar') +} + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + defaultConfig { + versionCode 12 + versionName "2.0" + minSdkVersion 16 + targetSdkVersion 16 + proguardFile 'config.pro' + consumerProguardFiles 'config.pro' + } + debug { + runProguard true + } + release { + runProguard true + } +} diff --git a/tests/libProguardJarDep/lib/config.pro b/tests/libProguardJarDep/lib/config.pro new file mode 100644 index 0000000..c3fd7bd --- /dev/null +++ b/tests/libProguardJarDep/lib/config.pro @@ -0,0 +1,3 @@ +-keep public class com.android.tests.basic.StringGetter { + public static java.lang.String getString(); +} diff --git a/tests/libProguardJarDep/lib/libs/util-1.0.jar b/tests/libProguardJarDep/lib/libs/util-1.0.jar Binary files differnew file mode 100644 index 0000000..55471dc --- /dev/null +++ b/tests/libProguardJarDep/lib/libs/util-1.0.jar diff --git a/tests/libProguardJarDep/lib/src/main/AndroidManifest.xml b/tests/libProguardJarDep/lib/src/main/AndroidManifest.xml new file mode 100644 index 0000000..950a35a --- /dev/null +++ b/tests/libProguardJarDep/lib/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.basic"> + <application /> +</manifest> diff --git a/tests/libProguardJarDep/lib/src/main/java/com/android/tests/basic/StringGetter.java b/tests/libProguardJarDep/lib/src/main/java/com/android/tests/basic/StringGetter.java new file mode 100644 index 0000000..e9e5e76 --- /dev/null +++ b/tests/libProguardJarDep/lib/src/main/java/com/android/tests/basic/StringGetter.java @@ -0,0 +1,23 @@ +package com.android.tests.basic; + +import java.lang.String; +import java.lang.StringBuffer; +import com.example.android.multiproject.person.People; +import com.example.android.multiproject.person.Person; + +public class StringGetter{ + + public static String getString() { + return getStringInternal(); + } + + private static String getStringInternal() { + StringBuffer sb = new StringBuffer(); + + Iterable<Person> people = new People(); + for (Person person : people) { + sb.append(person.getName()); + } + return sb.toString(); + } +} diff --git a/tests/libProguardJarDep/settings.gradle b/tests/libProguardJarDep/settings.gradle new file mode 100644 index 0000000..eedb2a1 --- /dev/null +++ b/tests/libProguardJarDep/settings.gradle @@ -0,0 +1,2 @@ +include 'app' +include 'lib' diff --git a/tests/libProguardJarDep/util/build.gradle b/tests/libProguardJarDep/util/build.gradle new file mode 100644 index 0000000..dff7725 --- /dev/null +++ b/tests/libProguardJarDep/util/build.gradle @@ -0,0 +1,8 @@ +apply plugin: 'java' + +dependencies { + compile 'com.google.guava:guava:11.0.2' +} + +sourceCompatibility = "1.6" +targetCompatibility = "1.6" diff --git a/tests/libProguardJarDep/util/src/main/java/com/example/android/multiproject/person/People.java b/tests/libProguardJarDep/util/src/main/java/com/example/android/multiproject/person/People.java new file mode 100644 index 0000000..8b99248 --- /dev/null +++ b/tests/libProguardJarDep/util/src/main/java/com/example/android/multiproject/person/People.java @@ -0,0 +1,10 @@ +package com.example.android.multiproject.person; + +import java.util.Iterator; +import com.google.common.collect.Lists; + +public class People implements Iterable<Person> { + public Iterator<Person> iterator() { + return Lists.newArrayList(new Person("Fred"), new Person("Barney")).iterator(); + } +} diff --git a/tests/libProguardJarDep/util/src/main/java/com/example/android/multiproject/person/Person.java b/tests/libProguardJarDep/util/src/main/java/com/example/android/multiproject/person/Person.java new file mode 100644 index 0000000..2f4aa9f --- /dev/null +++ b/tests/libProguardJarDep/util/src/main/java/com/example/android/multiproject/person/Person.java @@ -0,0 +1,13 @@ +package com.example.android.multiproject.person; + +public class Person { + private final String name; + + public Person(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/tests/libProguardLibDep/app/build.gradle b/tests/libProguardLibDep/app/build.gradle new file mode 100644 index 0000000..c52309a --- /dev/null +++ b/tests/libProguardLibDep/app/build.gradle @@ -0,0 +1,31 @@ +apply plugin: 'android' + +dependencies { + compile project(':lib') +} + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + testBuildType "proguard" + + defaultConfig { + versionCode 12 + versionName "2.0" + minSdkVersion 16 + targetSdkVersion 16 + } + + buildTypes { + proguard.initWith(buildTypes.debug) + proguard { + runProguard true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'config.pro' + } + } + + dexOptions { + incremental false + } +} diff --git a/tests/libProguardLibDep/app/config.pro b/tests/libProguardLibDep/app/config.pro new file mode 100644 index 0000000..e4aadb9 --- /dev/null +++ b/tests/libProguardLibDep/app/config.pro @@ -0,0 +1,3 @@ +-keep public class com.android.tests.basic.Main { + public void getObfuscatedMethod(); +} diff --git a/tests/libProguardLibDep/app/src/instrumentTest/java/com/android/tests/basic/MainTest.java b/tests/libProguardLibDep/app/src/instrumentTest/java/com/android/tests/basic/MainTest.java new file mode 100644 index 0000000..f7289d1 --- /dev/null +++ b/tests/libProguardLibDep/app/src/instrumentTest/java/com/android/tests/basic/MainTest.java @@ -0,0 +1,54 @@ +package com.android.tests.basic; + +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.MediumTest; +import android.widget.TextView; + +import java.lang.NoSuchMethodException; + +public class MainTest extends ActivityInstrumentationTestCase2<Main> { + + private TextView mTextView; + + /** + * 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); + mTextView = (TextView) a.findViewById(R.id.dateText); + } + + /** + * 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(mTextView); + } + + public void testTextViewContent() { + assertEquals("1234", mTextView.getText()); + } + + public void testConsumerProguardRules() { + try { + final Main a = getActivity(); + a.getObfuscatedMethod(); + fail("Excepted NoSuchMethodError"); + } catch (NoSuchMethodException e) { + // test passed + } + } +} + diff --git a/tests/libProguardLibDep/app/src/main/AndroidManifest.xml b/tests/libProguardLibDep/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..4f8d570 --- /dev/null +++ b/tests/libProguardLibDep/app/src/main/AndroidManifest.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.basic"> + <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> + + <uses-permission android:name="com.blah" /> + + <permission-group android:name="foo.permission-group.COST_MONEY" + android:label="@string/app_name" + android:description="@string/app_name" /> + + <permission android:name="foo.permission.SEND_SMS" + android:permissionGroup="foo.permission-group.COST_MONEY" + android:label="@string/app_name" + android:description="@string/app_name" /> + + <permission android:name="foo.blah.SEND_SMS" + android:permissionGroup="foo.permission-group.COST_MONEY" + android:label="@string/app_name" + android:description="@string/app_name" /> + +</manifest> diff --git a/tests/libProguardLibDep/app/src/main/java/com/android/tests/basic/Main.java b/tests/libProguardLibDep/app/src/main/java/com/android/tests/basic/Main.java new file mode 100644 index 0000000..8faebcd --- /dev/null +++ b/tests/libProguardLibDep/app/src/main/java/com/android/tests/basic/Main.java @@ -0,0 +1,46 @@ +package com.android.tests.basic; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.TextView; + +import java.lang.ClassNotFoundException; +import java.lang.NoSuchMethodException; +import java.lang.reflect.Method; + +public class Main extends Activity +{ + + private int foo = 1234; + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + TextView tv = (TextView) findViewById(R.id.dateText); + + try { + // use reflection to make sure the class wasn't obfuscated + Class<?> theClass = Class.forName("com.android.tests.basic.StringGetter"); + Method method = theClass.getDeclaredMethod("getString", int.class); + tv.setText((String) method.invoke(null, foo)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * use reflection to get a method that should be obfuscated + */ + public void getObfuscatedMethod() throws NoSuchMethodException{ + try { + Class<?> theClass = Class.forName("com.android.tests.basic.StringGetter"); + Method method = theClass.getDeclaredMethod("getStringInternal", int.class); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } +} diff --git a/tests/libProguardLibDep/app/src/main/res/drawable/icon.png b/tests/libProguardLibDep/app/src/main/res/drawable/icon.png Binary files differnew file mode 100644 index 0000000..a07c69f --- /dev/null +++ b/tests/libProguardLibDep/app/src/main/res/drawable/icon.png diff --git a/tests/libProguardLibDep/app/src/main/res/layout/main.xml b/tests/libProguardLibDep/app/src/main/res/layout/main.xml new file mode 100644 index 0000000..89ab091 --- /dev/null +++ b/tests/libProguardLibDep/app/src/main/res/layout/main.xml @@ -0,0 +1,20 @@ +<?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 - Basic" + android:id="@+id/text" + /> +<TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="" + android:id="@+id/dateText" + /> +</LinearLayout> + diff --git a/tests/libProguardLibDep/app/src/main/res/values/strings.xml b/tests/libProguardLibDep/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..60ea2d0 --- /dev/null +++ b/tests/libProguardLibDep/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">_Test-Basic</string> +</resources> diff --git a/tests/libProguardLibDep/build.gradle b/tests/libProguardLibDep/build.gradle new file mode 100644 index 0000000..62a4405 --- /dev/null +++ b/tests/libProguardLibDep/build.gradle @@ -0,0 +1,8 @@ +buildscript { + repositories { + maven { url '../../../../out/host/gradle/repo' } + } + dependencies { + classpath 'com.android.tools.build:gradle:0.5.0-SNAPSHOT' + } +} diff --git a/tests/libProguardLibDep/lib/build.gradle b/tests/libProguardLibDep/lib/build.gradle new file mode 100644 index 0000000..ce3ccf6 --- /dev/null +++ b/tests/libProguardLibDep/lib/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'android-library' + +dependencies { + compile project(':lib2') +} + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + defaultConfig { + versionCode 12 + versionName "2.0" + minSdkVersion 16 + targetSdkVersion 16 + proguardFile 'config.pro' + consumerProguardFiles 'consumerRules.pro' + } + release { + runProguard true + } +} diff --git a/tests/libProguardLibDep/lib/config.pro b/tests/libProguardLibDep/lib/config.pro new file mode 100644 index 0000000..4cf7cba --- /dev/null +++ b/tests/libProguardLibDep/lib/config.pro @@ -0,0 +1,3 @@ +-keep public class com.android.tests.basic.StringGetter { + public static java.lang.String getString(int); +} diff --git a/tests/libProguardLibDep/lib/consumerRules.pro b/tests/libProguardLibDep/lib/consumerRules.pro new file mode 100644 index 0000000..d09be16 --- /dev/null +++ b/tests/libProguardLibDep/lib/consumerRules.pro @@ -0,0 +1,6 @@ +-keep public class com.android.tests.basic.StringGetter { + public static java.lang.String getString(int); +} +-keep public class com.android.tests.basic.StringGetter { + public static java.lang.String getStringInternal(int); +} diff --git a/tests/libProguardLibDep/lib/src/main/AndroidManifest.xml b/tests/libProguardLibDep/lib/src/main/AndroidManifest.xml new file mode 100644 index 0000000..950a35a --- /dev/null +++ b/tests/libProguardLibDep/lib/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.basic"> + <application /> +</manifest> diff --git a/tests/libProguardLibDep/lib/src/main/java/com/android/tests/basic/StringGetter.java b/tests/libProguardLibDep/lib/src/main/java/com/android/tests/basic/StringGetter.java new file mode 100644 index 0000000..159f359 --- /dev/null +++ b/tests/libProguardLibDep/lib/src/main/java/com/android/tests/basic/StringGetter.java @@ -0,0 +1,23 @@ +package com.android.tests.basic; + +import java.lang.RuntimeException; +import java.lang.String; +import java.lang.reflect.Method; + +public class StringGetter{ + + public static String getString(int foo) { + return getStringInternal(foo); + } + + public static String getStringInternal(int foo) { + try { + // use reflection to make sure the class wasn't obfuscated + Class<?> theClass = Class.forName("com.android.tests.basic.StringProvider"); + Method method = theClass.getDeclaredMethod("getString", int.class); + return (String) method.invoke(null, foo); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/tests/libProguardLibDep/lib2/build.gradle b/tests/libProguardLibDep/lib2/build.gradle new file mode 100644 index 0000000..78da4d4 --- /dev/null +++ b/tests/libProguardLibDep/lib2/build.gradle @@ -0,0 +1,18 @@ +apply plugin: 'android-library' + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + defaultConfig { + versionCode 12 + versionName "2.0" + minSdkVersion 16 + targetSdkVersion 16 + proguardFile 'config.pro' + consumerProguardFiles 'config.pro' + } + release { + runProguard true + } +} diff --git a/tests/libProguardLibDep/lib2/config.pro b/tests/libProguardLibDep/lib2/config.pro new file mode 100644 index 0000000..3664f87 --- /dev/null +++ b/tests/libProguardLibDep/lib2/config.pro @@ -0,0 +1,3 @@ +-keep public class com.android.tests.basic.StringProvider { + public static java.lang.String getString(int); +} diff --git a/tests/libProguardLibDep/lib2/src/main/AndroidManifest.xml b/tests/libProguardLibDep/lib2/src/main/AndroidManifest.xml new file mode 100644 index 0000000..593a287 --- /dev/null +++ b/tests/libProguardLibDep/lib2/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.basic"> +</manifest> diff --git a/tests/libProguardLibDep/lib2/src/main/java/com/android/tests/basic/StringProvider.java b/tests/libProguardLibDep/lib2/src/main/java/com/android/tests/basic/StringProvider.java new file mode 100644 index 0000000..6d81901 --- /dev/null +++ b/tests/libProguardLibDep/lib2/src/main/java/com/android/tests/basic/StringProvider.java @@ -0,0 +1,8 @@ +package com.android.tests.basic; + +public class StringProvider { + + public static String getString(int foo) { + return Integer.toString(foo); + } +} diff --git a/tests/libProguardLibDep/settings.gradle b/tests/libProguardLibDep/settings.gradle new file mode 100644 index 0000000..d8ac2dc --- /dev/null +++ b/tests/libProguardLibDep/settings.gradle @@ -0,0 +1,3 @@ +include 'app' +include 'lib' +include 'lib2' diff --git a/tests/proguardLib/lib/build.gradle b/tests/proguardLib/lib/build.gradle index 3b209bf..efbffe6 100644 --- a/tests/proguardLib/lib/build.gradle +++ b/tests/proguardLib/lib/build.gradle @@ -9,6 +9,6 @@ android { versionName "2.0" minSdkVersion 16 targetSdkVersion 16 - proguardFile 'config.pro' + consumerProguardFiles 'config.pro' } -}
\ No newline at end of file +} |