diff options
author | Tor Norbye <tnorbye@google.com> | 2012-01-17 09:23:34 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-02-21 10:47:08 -0800 |
commit | 0bf1b2c94e8b3d829fd69d11f2efd550d6159cb9 (patch) | |
tree | b7026560ed728531c296d549ed8085f27d628be8 | |
parent | f9a57e464104e29c045939d84e8d3fb5d9becf7d (diff) | |
download | sdk-0bf1b2c94e8b3d829fd69d11f2efd550d6159cb9.zip sdk-0bf1b2c94e8b3d829fd69d11f2efd550d6159cb9.tar.gz sdk-0bf1b2c94e8b3d829fd69d11f2efd550d6159cb9.tar.bz2 |
Split ProGuard file into two halves
This changeset splits the proguard.cfg into two halves:
(1) All the general Android settings go into
$ANDROID_SDK/proguard/proguard-android.txt.
This defines shrinking rules like keep custom views, etc. The
crucial point is that this information is maintained and updated
by Tools updates, so whenever new APIs are added to Android, or
whenever bugs are found in the configuration such as flags needed
to work with Dalvik, we can make the updates - we don't have old
snapshots living on in projects.
(2) Any project specific settings go to proguard-project.txt in the
project.
(3) The proguard.config property in project.properties now refers to a
*path* of configuration files, which are all passed to ProGuard in
the given order. The code which processes this setting will
substitute android.sdk.home and user.home variables, so the path
does not have to be hardcoded to point to the project-android.txt
file.
The default project templates have been updated to include a
commented out configuration setting up proguard as described
above.
The default proguard file name was changed from proguard.cfg to
proguard-project.txt such that it can be directly opened in Eclipse
and to make it clear it's an editable text file.
Lint was updated to find the Proguard file via the proguard.config
property as well as via the old and new default names for projects not
enabled with ProGuard.
A subsequent CL will add a lint check which identifies projects
containing the old setup (full local configuration) and offer to
replace it with the new setup.
Change-Id: I44b4c97a160114c2382f02f843c95486a0dc9d6b
18 files changed, 269 insertions, 51 deletions
diff --git a/build/tools.atree b/build/tools.atree index f1d46d4..03868e2 100644 --- a/build/tools.atree +++ b/build/tools.atree @@ -65,7 +65,8 @@ bin/lint tools/lint # sdk.git Ant templates for project build files sdk/templates/build.template tools/lib/build.template -sdk/files/proguard.cfg tools/lib/proguard.cfg +sdk/files/proguard-project.txt tools/lib/proguard-project.txt +sdk/files/proguard-android.txt tools/proguard/proguard-android.txt # Ant Build Rules sdk/files/ant tools/ant diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java index 3ae9f64..5d2fe78 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java @@ -512,7 +512,7 @@ public class BuildHelper { return compiledPaths; } - public void runProguard(File proguardConfig, File inputJar, String[] jarFiles, + public void runProguard(List<File> proguardConfigs, File inputJar, String[] jarFiles, File obfuscatedJar, File logOutput) throws ProguardResultException, ProguardExecException, IOException { IAndroidTarget target = Sdk.getCurrent().getTarget(mProject); @@ -521,7 +521,10 @@ public class BuildHelper { List<String> command = new ArrayList<String>(); command.add(AdtPlugin.getOsAbsoluteProguard()); - command.add("@" + quotePath(proguardConfig.getAbsolutePath())); //$NON-NLS-1$ + for (File configFile : proguardConfigs) { + command.add("-include"); //$NON-NLS-1$ + command.add(quotePath(configFile.getAbsolutePath())); + } command.add("-injars"); //$NON-NLS-1$ StringBuilder sb = new StringBuilder(quotePath(inputJar.getAbsolutePath())); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java index 1e5171c..93fe43d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java @@ -16,6 +16,8 @@ package com.android.ide.eclipse.adt.internal.project; +import static com.android.sdklib.internal.project.ProjectProperties.PROPERTY_SDK; + import com.android.ide.eclipse.adt.AdtConstants; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AdtUtils; @@ -25,6 +27,7 @@ import com.android.ide.eclipse.adt.internal.build.DexException; import com.android.ide.eclipse.adt.internal.build.NativeLibInJarException; import com.android.ide.eclipse.adt.internal.build.ProguardExecException; import com.android.ide.eclipse.adt.internal.build.ProguardResultException; +import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; import com.android.ide.eclipse.adt.internal.sdk.ProjectState; import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.ide.eclipse.adt.io.IFileWrapper; @@ -58,6 +61,7 @@ import java.io.IOException; import java.io.OutputStream; import java.security.PrivateKey; import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; @@ -66,8 +70,10 @@ import java.util.jar.JarOutputStream; * Export helper to export release version of APKs. */ public final class ExportHelper { - - private final static String TEMP_PREFIX = "android_"; //$NON-NLS-1$ + private static final String HOME_PROPERTY = "user.home"; //$NON-NLS-1$ + private static final String HOME_PROPERTY_REF = "${" + HOME_PROPERTY + '}'; //$NON-NLS-1$ + private static final String SDK_PROPERTY_REF = "${" + PROPERTY_SDK + '}'; //$NON-NLS-1$ + private final static String TEMP_PREFIX = "android_"; //$NON-NLS-1$ /** * Exports a release version of the application created by the given project. @@ -75,7 +81,8 @@ public final class ExportHelper { * @param outputFile the file to write * @param key the key to used for signing. Can be null. * @param certificate the certificate used for signing. Can be null. - * @param monitor + * @param monitor progress monitor + * @throws CoreException if an error occurs */ public static void exportReleaseApk(IProject project, File outputFile, PrivateKey key, X509Certificate certificate, IProgressMonitor monitor) throws CoreException { @@ -151,13 +158,46 @@ public final class ExportHelper { ProjectProperties.PROPERTY_PROGUARD_CONFIG); boolean runProguard = false; - File proguardConfigFile = null; + List<File> proguardConfigFiles = null; if (proguardConfig != null && proguardConfig.length() > 0) { - proguardConfigFile = new File(proguardConfig); - if (proguardConfigFile.isAbsolute() == false) { - proguardConfigFile = new File(project.getLocation().toFile(), proguardConfig); + // Be tolerant with respect to file and path separators just like + // Ant is. Allow "/" in the property file to mean whatever the file + // separator character is: + if (File.separatorChar != '/' && proguardConfig.indexOf('/') != -1) { + proguardConfig = proguardConfig.replace('/', File.separatorChar); + } + // Also split path: no need to convert to File.pathSeparator because we'll + // be splitting the path ourselves right here, so just ensure that both + // ':' and ';' work: + if (proguardConfig.indexOf(';') != -1) { + proguardConfig = proguardConfig.replace(';', ':'); + } + String[] paths = proguardConfig.split(":"); //$NON-NLS-1$ + + for (String path : paths) { + if (path.startsWith(SDK_PROPERTY_REF)) { + path = AdtPrefs.getPrefs().getOsSdkFolder() + + path.substring(SDK_PROPERTY_REF.length()); + } else if (path.startsWith(HOME_PROPERTY_REF)) { + path = System.getProperty(HOME_PROPERTY) + + path.substring(HOME_PROPERTY_REF.length()); + } + File proguardConfigFile = new File(path); + if (proguardConfigFile.isAbsolute() == false) { + proguardConfigFile = new File(project.getLocation().toFile(), path); + } + if (proguardConfigFile.isFile()) { + if (proguardConfigFiles == null) { + proguardConfigFiles = new ArrayList<File>(); + } + proguardConfigFiles.add(proguardConfigFile); + runProguard = true; + } else { + throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, + "Invalid proguard configuration file path " + proguardConfigFile + + " does not exist or is not a regular file", null)); + } } - runProguard = proguardConfigFile.isFile(); } String[] dxInput; @@ -188,7 +228,7 @@ public final class ExportHelper { obfuscatedJar.deleteOnExit(); // run proguard - helper.runProguard(proguardConfigFile, inputJar, jarFiles, obfuscatedJar, + helper.runProguard(proguardConfigFiles, inputJar, jarFiles, obfuscatedJar, new File(project.getLocation().toFile(), SdkConstants.FD_PROGUARD)); // dx input is proguard's output diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java index 97da3ab..7424d6c 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java @@ -606,7 +606,10 @@ public class NewProjectCreator { File libFolder = new File((String) parameters.get(PARAM_SDK_TOOLS_DIR), SdkConstants.FD_LIB); addLocalFile(project, - new File(libFolder, SdkConstants.FN_PROGUARD_CFG), + new File(libFolder, SdkConstants.FN_PROJECT_PROGUARD_FILE), + // Write ProGuard config files with the extension .pro which + // is what is used in the ProGuard documentation and samples + SdkConstants.FN_PROJECT_PROGUARD_FILE, monitor); // Set output location @@ -1080,13 +1083,14 @@ public class NewProjectCreator { /** * Adds a file to the root of the project * @param project the project to add the file to. + * @param destName the name to write the file as * @param source the file to add. It'll keep the same filename once copied into the project. * @throws FileNotFoundException * @throws CoreException */ - private void addLocalFile(IProject project, File source, IProgressMonitor monitor) - throws FileNotFoundException, CoreException { - IFile dest = project.getFile(source.getName()); + private void addLocalFile(IProject project, File source, String destName, + IProgressMonitor monitor) throws FileNotFoundException, CoreException { + IFile dest = project.getFile(destName); if (dest.exists() == false) { FileInputStream stream = new FileInputStream(source); dest.create(stream, false /* force */, new SubProgressMonitor(monitor, 10)); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java index d5bd895..ea78127 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java @@ -15,6 +15,9 @@ */ package com.android.ide.eclipse.adt.internal.wizards.newproject; +import static com.android.sdklib.SdkConstants.FN_PROJECT_PROGUARD_FILE; +import static com.android.sdklib.SdkConstants.OS_SDK_TOOLS_LIB_FOLDER; + import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode; @@ -26,6 +29,8 @@ import org.eclipse.jface.wizard.Wizard; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; +import java.io.File; + /** * A "New Android Project" Wizard. @@ -105,6 +110,16 @@ public class NewProjectWizard extends Wizard implements INewWizard { @Override public boolean performFinish() { + File file = new File(AdtPlugin.getOsSdkFolder(), OS_SDK_TOOLS_LIB_FOLDER + File.separator + + FN_PROJECT_PROGUARD_FILE); + if (!file.exists()) { + AdtPlugin.displayError("Tools Out of Date?", + String.format("It looks like you do not have the latest version of the " + + "SDK Tools installed. Make sure you update via the SDK Manager " + + "first. (Could not find %1$s)", file.getPath())); + return false; + } + NewProjectCreator creator = new NewProjectCreator(mValues, getContainer()); if (!(creator.createAndroidProjects())) { return false; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ProjectNamePage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ProjectNamePage.java index 3db3353..6de6556 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ProjectNamePage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ProjectNamePage.java @@ -18,8 +18,11 @@ package com.android.ide.eclipse.adt.internal.wizards.newproject; import static com.android.ide.eclipse.adt.AdtUtils.capitalize; import static com.android.ide.eclipse.adt.AdtUtils.stripWhitespace; import static com.android.ide.eclipse.adt.internal.wizards.newproject.ApplicationInfoPage.ACTIVITY_NAME_SUFFIX; +import static com.android.sdklib.SdkConstants.FN_PROJECT_PROGUARD_FILE; +import static com.android.sdklib.SdkConstants.OS_SDK_TOOLS_LIB_FOLDER; import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.internal.VersionCheck; import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode; import com.android.sdklib.SdkConstants; @@ -85,6 +88,15 @@ class ProjectNamePage extends WizardPage implements SelectionListener, ModifyLis private Button mBrowseButton; private Label mLocationLabel; private WorkingSetGroup mWorkingSetGroup; + /** + * Whether we've made sure the Tools are up to date (enough that all the + * resources required by the New Project wizard are present -- we don't + * necessarily check for newer versions than that here; that's done by + * {@link VersionCheck}, though that check doesn't <b>enforce</b> an update + * since it needs to allow the user to proceed to access the SDK manager + * etc.) + */ + private boolean mCheckedSdkUptodate; /** * Create the wizard. @@ -446,6 +458,20 @@ class ProjectNamePage extends WizardPage implements SelectionListener, ModifyLis } } + if (!mCheckedSdkUptodate) { + // Ensure that we have a recent enough version of the Tools that the right templates + // are available + File file = new File(AdtPlugin.getOsSdkFolder(), OS_SDK_TOOLS_LIB_FOLDER + + File.separator + FN_PROJECT_PROGUARD_FILE); + if (!file.exists()) { + status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, + String.format("You do not have the latest version of the " + + "SDK Tools installed: Please update. (Missing %1$s)", file.getPath())); + } else { + mCheckedSdkUptodate = true; + } + } + // -- update UI & enable finish if there's no error setPageComplete(status == null || status.getSeverity() != IStatus.ERROR); if (status != null) { diff --git a/files/ant/build.xml b/files/ant/build.xml index 622d558..e47c3fe 100644 --- a/files/ant/build.xml +++ b/files/ant/build.xml @@ -766,13 +766,24 @@ </firstmatchmapper> </pathconvert> + <!-- Turn the path property ${proguard.config} from an A:B:C property + into a series of includes: -include A -include B -include C + suitable for processing by the ProGuard task. Note - this does + not include the leading '-include "' or the closing '"'; those + are added under the <proguard> call below. + --> + <path id="proguard.configpath"> + <pathelement path="${proguard.config}"/> + </path> + <pathconvert pathsep='" -include "' property="proguard.configcmd" refid="proguard.configpath"/> + <mkdir dir="${obfuscate.absolute.dir}" /> <delete file="${preobfuscate.jar.file}"/> <delete file="${obfuscated.jar.file}"/> <jar basedir="${out.classes.absolute.dir}" destfile="${preobfuscate.jar.file}" /> <proguard> - @${proguard.config} + -include "${proguard.configcmd}" -injars ${project.jars} -outjars "${obfuscated.jar.file}" -libraryjars ${android.libraryjars} diff --git a/files/proguard.cfg b/files/proguard-android.txt index 53f41fe..b3d2fe1 100644 --- a/files/proguard.cfg +++ b/files/proguard-android.txt @@ -1,16 +1,29 @@ --optimizationpasses 5 +# This is a configuration file for ProGuard. +# http://proguard.sourceforge.net/index.html#manual/usage.html + -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. +# Optimization is turned off by default. Dex does not like code run +# through the ProGuard optimize and preverify steps (and performs some +# of these optimizations on its own). -dontoptimize -dontpreverify +# If you want to enable optimization, you should include the +# following: +# -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/* +# -optimizationpasses 5 +# -allowaccessmodification +# +# Note that you cannot just include these flags in your own +# configuration file; if you are including this file, optimization +# will be turned off. You'll need to either edit this file, or +# duplicate the contents of this file and remove the include of this +# file from your project's proguard.config path property. + +-keepattributes *Annotation* -keep public class * extends android.app.Activity -keep public class * extends android.app.Application -keep public class * extends android.app.Service diff --git a/files/proguard-project.txt b/files/proguard-project.txt new file mode 100644 index 0000000..f2fe155 --- /dev/null +++ b/files/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} 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 31622eb..652e875 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 @@ -21,7 +21,8 @@ import static com.android.tools.lint.detector.api.LintConstants.ATTR_IGNORE; import static com.android.tools.lint.detector.api.LintConstants.DOT_CLASS; import static com.android.tools.lint.detector.api.LintConstants.DOT_JAR; import static com.android.tools.lint.detector.api.LintConstants.DOT_JAVA; -import static com.android.tools.lint.detector.api.LintConstants.PROGUARD_CFG; +import static com.android.tools.lint.detector.api.LintConstants.OLD_PROGUARD_FILE; +import static com.android.tools.lint.detector.api.LintConstants.PROGUARD_FILE; import static com.android.tools.lint.detector.api.LintConstants.RES_FOLDER; import static com.android.tools.lint.detector.api.LintConstants.SUPPRESS_ALL; import static com.android.tools.lint.detector.api.LintConstants.SUPPRESS_LINT; @@ -46,6 +47,8 @@ import com.android.tools.lint.detector.api.Scope; import com.android.tools.lint.detector.api.Severity; import com.android.tools.lint.detector.api.XmlContext; import com.google.common.annotations.Beta; +import com.google.common.base.CharMatcher; +import com.google.common.base.Splitter; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import com.google.common.io.ByteStreams; @@ -215,8 +218,6 @@ public class LintDriver { mScope.add(Scope.MANIFEST); } else if (name.endsWith(".xml")) { mScope.add(Scope.RESOURCE_FILE); - } else if (name.equals(PROGUARD_CFG)) { - mScope.add(Scope.PROGUARD_FILE); } else if (name.equals(RES_FOLDER) || file.getParent().equals(RES_FOLDER)) { mScope.add(Scope.ALL_RESOURCE_FILES); @@ -225,6 +226,8 @@ public class LintDriver { mScope.add(Scope.JAVA_FILE); } else if (name.endsWith(DOT_CLASS)) { mScope.add(Scope.CLASS_FILE); + } else if (name.equals(OLD_PROGUARD_FILE) || name.equals(PROGUARD_FILE)) { + mScope.add(Scope.PROGUARD_FILE); } } } else { @@ -740,18 +743,50 @@ public class LintDriver { } if (project == main && mScope.contains(Scope.PROGUARD_FILE)) { - List<Detector> detectors = mScopeDetectors.get(Scope.PROGUARD_FILE); - if (detectors != null) { - File file = new File(project.getDir(), PROGUARD_CFG); + checkProGuard(project, main); + } + } + + private void checkProGuard(Project project, Project main) { + List<Detector> detectors = mScopeDetectors.get(Scope.PROGUARD_FILE); + if (detectors != null) { + Project p = main != null ? main : project; + List<File> files = new ArrayList<File>(); + String paths = p.getProguardPath(); + if (paths != null) { + Splitter splitter = Splitter.on(CharMatcher.anyOf(":;")); //$NON-NLS-1$ + for (String path : splitter.split(paths)) { + if (path.contains("${")) { //$NON-NLS-1$ + // Don't analyze the global/user proguard files + continue; + } + File file = new File(path); + if (!file.isAbsolute()) { + file = new File(project.getDir(), path); + } + if (file.exists()) { + files.add(file); + } + } + } + if (files.isEmpty()) { + File file = new File(project.getDir(), OLD_PROGUARD_FILE); if (file.exists()) { - Context context = new Context(this, project, main, file); - fireEvent(EventType.SCANNING_FILE, context); - for (Detector detector : detectors) { - if (detector.appliesTo(context, file)) { - detector.beforeCheckFile(context); - detector.run(context); - detector.afterCheckFile(context); - } + files.add(file); + } + file = new File(project.getDir(), PROGUARD_FILE); + if (file.exists()) { + files.add(file); + } + } + for (File file : files) { + Context context = new Context(this, project, main, file); + fireEvent(EventType.SCANNING_FILE, context); + for (Detector detector : detectors) { + if (detector.appliesTo(context, file)) { + detector.beforeCheckFile(context); + detector.run(context); + detector.afterCheckFile(context); } } } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java index 371046f..3e32908 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java @@ -217,7 +217,9 @@ public class LintConstants { // Filenames and folder names public static final String ANDROID_MANIFEST_XML = "AndroidManifest.xml"; //$NON-NLS-1$ - public static final String PROGUARD_CFG = "proguard.cfg"; //$NON-NLS-1$ + public static final String OLD_PROGUARD_FILE = "proguard.cfg"; //$NON-NLS-1$ + public static final String PROGUARD_FILE = "proguard-project.txt"; //$NON-NLS-1$ + public static final String RES_FOLDER = "res"; //$NON-NLS-1$ public static final String DOT_XML = ".xml"; //$NON-NLS-1$ public static final String DOT_GIF = ".gif"; //$NON-NLS-1$ @@ -257,6 +259,7 @@ public class LintConstants { // Project properties public static final String ANDROID_LIBRARY = "android.library"; //$NON-NLS-1$ + public static final String PROGUARD_CONFIG = "proguard.config"; //$NON-NLS-1$ public static final String ANDROID_LIBRARY_REFERENCE_FORMAT = "android.library.reference.%1$d";//$NON-NLS-1$ public static final String PROJECT_PROPERTIES = "project.properties";//$NON-NLS-1$ diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java index 910ee2f..d0de34c 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java @@ -23,6 +23,7 @@ import static com.android.tools.lint.detector.api.LintConstants.ANDROID_URI; import static com.android.tools.lint.detector.api.LintConstants.ATTR_MIN_SDK_VERSION; import static com.android.tools.lint.detector.api.LintConstants.ATTR_PACKAGE; import static com.android.tools.lint.detector.api.LintConstants.ATTR_TARGET_SDK_VERSION; +import static com.android.tools.lint.detector.api.LintConstants.PROGUARD_CONFIG; import static com.android.tools.lint.detector.api.LintConstants.PROJECT_PROPERTIES; import static com.android.tools.lint.detector.api.LintConstants.TAG_USES_SDK; import static com.android.tools.lint.detector.api.LintConstants.VALUE_TRUE; @@ -71,6 +72,7 @@ public class Project { private int mTargetSdk = -1; private boolean mLibrary; private String mName; + private String mProguardPath; /** The SDK info, if any */ private SdkInfo mSdkInfo; @@ -121,6 +123,7 @@ public class Project { properties.load(is); String value = properties.getProperty(ANDROID_LIBRARY); mLibrary = VALUE_TRUE.equals(value); + mProguardPath = properties.getProperty(PROGUARD_CONFIG); for (int i = 1; i < 1000; i++) { String key = String.format(ANDROID_LIBRARY_REFERENCE_FORMAT, i); @@ -545,6 +548,17 @@ public class Project { } /** + * Returns the proguard path configured for this project, or null if ProGuard is + * not configured. + * + * @return the proguard path, or null + */ + @Nullable + public String getProguardPath() { + return mProguardPath; + } + + /** * Returns the name of the project * * @return the name of the project, never null 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 95de739..d4200ed 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 @@ -36,8 +36,8 @@ public class ProguardDetector extends Detector { /** The main issue discovered by this detector */ public static final Issue ISSUE = Issue.create( "Proguard", //$NON-NLS-1$ - "Looks for problems in proguard.cfg files", - "Using -keepclasseswithmembernames in a proguard.cfg file is not " + + "Looks for problems in proguard config files", + "Using -keepclasseswithmembernames in a proguard config file is not " + "correct; it can cause some symbols to be renamed which should not be.\n" + "Earlier versions of ADT used to create proguard.cfg files with the " + "wrong format. Instead of -keepclasseswithmembernames use " + @@ -69,7 +69,7 @@ public class ProguardDetector extends Detector { @Override public boolean appliesTo(Context context, File file) { - return file.getName().equals("proguard.cfg"); //$NON-NLS-1$ + return true; } @Override 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 019effd..d6bf514 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 @@ -31,4 +31,20 @@ public class ProguardDetectorTest extends AbstractCheckTest { "instead of -keepclasseswithmembernames", lintFiles("proguard.cfg")); } + + public void testProguardNewPath() throws Exception { + assertEquals( + "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", + lintProject( + "proguard.cfg=>myfile.txt", + "proguard.properties=>project.properties")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/proguard.properties b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/proguard.properties new file mode 100644 index 0000000..989c3c7 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/proguard.properties @@ -0,0 +1,2 @@ +target=android-14 +proguard.config=${sdk.dir}/foo.cfg:${user.home}/bar.pro;myfile.txt diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java index 4f3ed9f..e21e14f 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java @@ -166,8 +166,10 @@ public final class SdkConstants { */ public final static String FN_GDBSERVER = "gdbserver"; //$NON-NLS-1$ - /** default proguard config file */ - public final static String FN_PROGUARD_CFG = "proguard.cfg"; //$NON-NLS-1$ + /** global Android proguard config file */ + public final static String FN_ANDROID_PROGUARD_FILE = "proguard-android.txt"; //$NON-NLS-1$ + /** default proguard config file with new file extension (for project specific stuff) */ + public final static String FN_PROJECT_PROGUARD_FILE = "proguard-project.txt"; //$NON-NLS-1$ /* Folder Names for Android Projects . */ @@ -385,7 +387,6 @@ public final class SdkConstants { /** SDK property: default skin */ public final static String PROP_SDK_DEFAULT_SKIN = "sdk.skin.default"; //$NON-NLS-1$ - /* Android Class Constants */ public final static String CLASS_ACTIVITY = "android.app.Activity"; //$NON-NLS-1$ public final static String CLASS_APPLICATION = "android.app.Application"; //$NON-NLS-1$ diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java index c3d7993..721d165 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java @@ -369,8 +369,8 @@ public class ProjectCreator { keywords); // install the proguard config file. - installTemplate(SdkConstants.FN_PROGUARD_CFG, - new File(projectFolder, SdkConstants.FN_PROGUARD_CFG), + installTemplate(SdkConstants.FN_PROJECT_PROGUARD_FILE, + new File(projectFolder, SdkConstants.FN_PROJECT_PROGUARD_FILE), null /*keywords*/); } catch (Exception e) { mLog.error(e, null); @@ -751,8 +751,10 @@ public class ProjectCreator { if (hasProguard == false) { try { - installTemplate(SdkConstants.FN_PROGUARD_CFG, - new File(projectFolder, SdkConstants.FN_PROGUARD_CFG), + installTemplate(SdkConstants.FN_PROJECT_PROGUARD_FILE, + // Write ProGuard config files with the extension .pro which + // is what is used in the ProGuard documentation and samples + new File(projectFolder, SdkConstants.FN_PROJECT_PROGUARD_FILE), null /*placeholderMap*/); } catch (ProjectCreateException e) { mLog.error(e, null); diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java index 3a73bef..2bb6b71 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java @@ -16,6 +16,11 @@ package com.android.sdklib.internal.project; +import static com.android.sdklib.SdkConstants.FD_PROGUARD; +import static com.android.sdklib.SdkConstants.FD_TOOLS; +import static com.android.sdklib.SdkConstants.FN_ANDROID_PROGUARD_FILE; +import static com.android.sdklib.SdkConstants.FN_PROJECT_PROGUARD_FILE; + import com.android.io.FolderWrapper; import com.android.io.IAbstractFile; import com.android.io.IAbstractFolder; @@ -24,6 +29,7 @@ import com.android.sdklib.ISdkLog; import com.android.sdklib.SdkConstants; import java.io.BufferedReader; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; @@ -163,7 +169,7 @@ public class ProjectProperties { "# This file is automatically generated by Android Tools.\n" + "# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n" + "#\n" + - "# This file must *NOT* be checked in Version Control Systems,\n" + + "# This file must *NOT* be checked into Version Control Systems,\n" + "# as it contains information specific to your local configuration.\n" + "\n"; @@ -174,16 +180,22 @@ public class ProjectProperties { "#\n" + "# This file must be checked in Version Control Systems.\n" + "#\n" + - "# To customize properties used by the Ant build system use,\n" + + "# To customize properties used by the Ant build system edit\n" + "# \"ant.properties\", and override values to adapt the script to your\n" + "# project structure.\n" + + "#\n" + + "# To enable ProGuard to shrink and obfuscate your code, uncomment this " + + "(available properties: sdk.dir, user.home):\n" + + "#" + PROPERTY_PROGUARD_CONFIG + "=${" + PROPERTY_SDK +"}" + File.separator + + FD_TOOLS + File.separator + FD_PROGUARD + File.separator + + FN_ANDROID_PROGUARD_FILE + ':' + FN_PROJECT_PROGUARD_FILE +'\n' + "\n"; private final static String BUILD_HEADER = // 1-------10--------20--------30--------40--------50--------60--------70--------80 "# This file is used to override default values used by the Ant build system.\n" + "#\n" + - "# This file must be checked in Version Control Systems, as it is\n" + + "# This file must be checked into Version Control Systems, as it is\n" + "# integral to the build system of your project.\n" + "\n" + "# This file is only used by the Ant script.\n" + |