diff options
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 4ebc9ed..b79914c 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 cb47f92..6788652 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 @@ -242,7 +242,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$ @@ -283,6 +285,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" + |