diff options
author | Tor Norbye <tnorbye@google.com> | 2012-02-08 07:26:42 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-02-22 11:17:45 -0800 |
commit | 7ebecc2865fd76fb683d1dfb5914cf445dae7fb9 (patch) | |
tree | 6ce2638745ed07cf15200533adf8f89096eb2735 /lint | |
parent | 47b83f51857c91ac37a696bcaf673cc13a8d3912 (diff) | |
download | sdk-7ebecc2865fd76fb683d1dfb5914cf445dae7fb9.zip sdk-7ebecc2865fd76fb683d1dfb5914cf445dae7fb9.tar.gz sdk-7ebecc2865fd76fb683d1dfb5914cf445dae7fb9.tar.bz2 |
Add lint check for "old" proguard configurations with generic Android config
Change-Id: I79cbdf874cffe78eb62f9af2e22e6cc780853e6a
Diffstat (limited to 'lint')
9 files changed, 254 insertions, 15 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java index b79914c..3f32727 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java @@ -218,6 +218,8 @@ public class LintDriver { mScope.add(Scope.MANIFEST); } else if (name.endsWith(".xml")) { mScope.add(Scope.RESOURCE_FILE); + } else if (name.equals(PROGUARD_FILE) || name.equals(OLD_PROGUARD_FILE)) { + mScope.add(Scope.PROGUARD_FILE); } else if (name.equals(RES_FOLDER) || file.getParent().equals(RES_FOLDER)) { mScope.add(Scope.ALL_RESOURCE_FILES); diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java index 258a267..3af53ad 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java @@ -53,7 +53,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { private static final List<Issue> sIssues; static { - final int initialCapacity = 81; + final int initialCapacity = 82; List<Issue> issues = new ArrayList<Issue>(initialCapacity); issues.add(AccessibilityDetector.ISSUE); @@ -89,7 +89,8 @@ public class BuiltinIssueRegistry extends IssueRegistry { issues.add(TranslationDetector.MISSING); issues.add(HardcodedValuesDetector.ISSUE); issues.add(Utf8Detector.ISSUE); - issues.add(ProguardDetector.ISSUE); + issues.add(ProguardDetector.WRONGKEEP); + issues.add(ProguardDetector.SPLITCONFIG); issues.add(PxUsageDetector.ISSUE); issues.add(TextFieldDetector.ISSUE); issues.add(TextViewDetector.ISSUE); diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ProguardDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ProguardDetector.java index d4200ed..c062507 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ProguardDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ProguardDetector.java @@ -16,6 +16,9 @@ package com.android.tools.lint.checks; +import static com.android.tools.lint.detector.api.LintConstants.PROGUARD_CONFIG; +import static com.android.tools.lint.detector.api.LintConstants.PROJECT_PROPERTIES; + import com.android.tools.lint.detector.api.Category; import com.android.tools.lint.detector.api.Context; import com.android.tools.lint.detector.api.Detector; @@ -34,7 +37,7 @@ import java.util.EnumSet; public class ProguardDetector extends Detector { /** The main issue discovered by this detector */ - public static final Issue ISSUE = Issue.create( + public static final Issue WRONGKEEP = Issue.create( "Proguard", //$NON-NLS-1$ "Looks for problems in proguard config files", "Using -keepclasseswithmembernames in a proguard config file is not " + @@ -51,18 +54,98 @@ public class ProguardDetector extends Detector { EnumSet.of(Scope.PROGUARD_FILE)).setMoreInfo( "http://http://code.google.com/p/android/issues/detail?id=16384"); //$NON-NLS-1$ + /** Finds ProGuard files that contain non-project specific configuration + * locally and suggests replacing it with an include path */ + public static final Issue SPLITCONFIG = Issue.create( + "ProguardSplit", //$NON-NLS-1$ + "Checks for old proguard.cfg files that contain generic Android rules", + + "Earlier versions of the Android tools bundled a single \"proguard.cfg\" file " + + "containing a ProGuard configuration file suitable for Android shrinking and " + + "obfuscation. However, that version was copied into new projects, which " + + "means that it does not continue to get updated as we improve the default " + + "ProGuard rules for Android.\n" + + "\n" + + "In the new version of the tools, we have split the ProGuard configuration " + + "into two halves:\n" + + "* A simple configuration file containing only project-specific flags, in " + + "your project\n" + + "* A generic configuration file containing the recommended set of ProGuard " + + "options for Android projects. This generic file lives in the SDK install " + + "directory which means that it gets updated along with the tools.\n" + + "\n" + + "In order for this to work, the proguard.config property in the " + + "project.properties file now refers to a path, so you can reference both " + + "the generic file as well as your own (and any additional files too).\n" + + "\n" + + "To migrate your project to the new setup, create a new proguard-project.txt file " + + "in your project containing any project specific ProGuard flags as well as " + + "any customizations you have made, then update your project.properties file " + + "to contain:\n" + + "proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt", + + Category.CORRECTNESS, + 3, + Severity.WARNING, + ProguardDetector.class, + EnumSet.of(Scope.PROGUARD_FILE)); + @Override public void run(Context context) { String contents = context.getContents(); if (contents != null) { - int index = contents.indexOf( - // Old pattern: - "-keepclasseswithmembernames class * {\n" + //$NON-NLS-1$ - " public <init>(android."); //$NON-NLS-1$ - if (index != -1) { - context.report(ISSUE, - Location.create(context.file, contents, index, index), - "Obsolete proguard file; use -keepclasseswithmembers instead of -keepclasseswithmembernames", null); + if (context.isEnabled(WRONGKEEP)) { + int index = contents.indexOf( + // Old pattern: + "-keepclasseswithmembernames class * {\n" + //$NON-NLS-1$ + " public <init>(android."); //$NON-NLS-1$ + if (index != -1) { + context.report(WRONGKEEP, + Location.create(context.file, contents, index, index), + "Obsolete ProGuard file; use -keepclasseswithmembers instead of " + + "-keepclasseswithmembernames", null); + } + } + if (context.isEnabled(SPLITCONFIG)) { + int index = contents.indexOf("-keep public class * extends android.app.Activity"); + if (index != -1) { + // Only complain if project.properties actually references this file; + // no need to bother the users who got a default proguard.cfg file + // when they created their projects but haven't actually hooked it up + // to shrinking & obfuscation. + File propertyFile = new File(context.file.getParentFile(), PROJECT_PROPERTIES); + if (!propertyFile.exists()) { + return; + } + String properties = context.getClient().readFile(propertyFile); + int i = properties.indexOf(PROGUARD_CONFIG); + if (i == -1) { + return; + } + // Make sure the entry isn't just commented out, such as + // # To enable ProGuard to shrink and obfuscate your code, uncomment this: + // #proguard.config=proguard.cfg + for (; i >= 0; i--) { + char c = properties.charAt(i); + if (c == '#') { + return; + } + if (c == '\n') { + break; + } + } + if (properties.contains(PROGUARD_CONFIG)) { + context.report(SPLITCONFIG, + Location.create(context.file, contents, index, index), + String.format( + "Local ProGuard configuration contains general Android " + + "configuration: Inherit these settings instead? " + + "Modify project.properties to define " + + "proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:%1$s" + + " and then keep only project-specific configuration here", + context.file.getName()), null); + } + } } } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ProguardDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ProguardDetectorTest.java index d6bf514..f3d872b 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ProguardDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ProguardDetectorTest.java @@ -27,24 +27,60 @@ public class ProguardDetectorTest extends AbstractCheckTest { public void testProguard() throws Exception { assertEquals( - "proguard.cfg:21: Error: Obsolete proguard file; use -keepclasseswithmembers " + + "proguard.cfg:21: Error: Obsolete ProGuard file; use -keepclasseswithmembers " + "instead of -keepclasseswithmembernames", lintFiles("proguard.cfg")); } public void testProguardNewPath() throws Exception { assertEquals( - "proguard-project.txt:21: Error: Obsolete proguard file; use " + + "proguard-project.txt:21: Error: Obsolete ProGuard file; use " + "-keepclasseswithmembers instead of -keepclasseswithmembernames", lintFiles("proguard.cfg=>proguard-project.txt")); } public void testProguardRandomName() throws Exception { assertEquals( - "myfile.txt:21: Error: Obsolete proguard file; use " + - "-keepclasseswithmembers instead of -keepclasseswithmembernames", + "myfile.txt:21: Error: Obsolete ProGuard file; use -keepclasseswithmembers " + + "instead of -keepclasseswithmembernames\n" + + "myfile.txt:8: Warning: Local ProGuard configuration contains general " + + "Android configuration: Inherit these settings instead? Modify " + + "project.properties to define proguard.config=${sdk.dir}/tools/proguard/" + + "proguard-android.txt:myfile.txt and then keep only project-specific " + + "configuration here", lintProject( "proguard.cfg=>myfile.txt", "proguard.properties=>project.properties")); } + + public void testSilent() throws Exception { + assertEquals( + "No warnings.", + + lintFiles( + "proguard.pro=>proguard.cfg", + "project.properties1=>project.properties")); + } + + public void testSilent2() throws Exception { + assertEquals( + "No warnings.", + + lintFiles( + "proguard.pro=>proguard.cfg", + "project.properties3=>project.properties")); + } + + public void testSplit() throws Exception { + assertEquals( + "proguard.cfg:14: Warning: Local ProGuard configuration contains general " + + "Android configuration: Inherit these settings instead? Modify " + + "project.properties to define " + + "proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard.cfg " + + "and then keep only project-specific configuration here", + + lintFiles( + "proguard.pro=>proguard.cfg", + "project.properties2=>project.properties")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/proguard.pro b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/proguard.pro new file mode 100644 index 0000000..53f41fe --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/proguard.pro @@ -0,0 +1,64 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-verbose +-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/* +-allowaccessmodification +-keepattributes *Annotation* + + +# dex does not like code run through proguard optimize and preverify steps. +-dontoptimize +-dontpreverify + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgent +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native +-keepclasseswithmembernames class * { + native <methods>; +} + +-keep public class * extends android.view.View { + public <init>(android.content.Context); + public <init>(android.content.Context, android.util.AttributeSet); + public <init>(android.content.Context, android.util.AttributeSet, int); + public void set*(...); +} + +-keepclasseswithmembers class * { + public <init>(android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembers class * { + public <init>(android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers class * extends android.app.Activity { + public void *(android.view.View); +} + +# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} + +-keepclassmembers class **.R$* { + public static <fields>; +} + +# The support library contains references to newer platform versions. +# Don't warn about those in case this app is linking against an older +# platform version. We know about them, and they are safe. +-dontwarn android.support.** diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties1 b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties1 new file mode 100644 index 0000000..2b783dd --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties1 @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this: +#proguard.config=proguard.cfg + +# Project target. +target=android-3 diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties2 b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties2 new file mode 100644 index 0000000..d9a28ec --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties2 @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this: +proguard.config=proguard.cfg + +# Project target. +target=android-3 diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties3 b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties3 new file mode 100644 index 0000000..3cb9d31 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties3 @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-3 diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties4 b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties4 new file mode 100644 index 0000000..fca9311 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/project.properties4 @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this: +proguard.config=${sdk.dir}/tools/proguard/android-defaults.pro:proguard.pro + +# Project target. +target=android-3 |