aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/tools.atree3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java58
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java12
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java15
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ProjectNamePage.java26
-rw-r--r--files/ant/build.xml13
-rw-r--r--files/proguard-android.txt (renamed from files/proguard.cfg)25
-rw-r--r--files/proguard-project.txt20
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java63
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java5
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java14
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ProguardDetector.java6
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ProguardDetectorTest.java16
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/proguard.properties2
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java7
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java10
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java18
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" +