aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java10
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java46
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/EclipseLintClient.java10
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFixGenerator.java6
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java10
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java4
-rw-r--r--lint/cli/.classpath11
-rw-r--r--lint/cli/Android.mk1
-rw-r--r--lint/cli/etc/manifest.txt2
-rw-r--r--lint/cli/src/com/android/tools/lint/HtmlReporter.java18
-rw-r--r--lint/cli/src/com/android/tools/lint/hololike.css41
-rw-r--r--lint/libs/lint_api/.classpath1
-rw-r--r--lint/libs/lint_api/Android.mk1
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java75
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java36
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Issue.java154
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java9
-rw-r--r--lint/libs/lint_checks/.classpath1
-rw-r--r--lint/libs/lint_checks/Android.mk3
-rw-r--r--lint/libs/lint_checks/NOTICE190
-rw-r--r--lint/libs/lint_checks/etc/manifest.txt1
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/AccessibilityDetector.java2
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/AlwaysShowActionDetector.java16
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/AnnotationDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiDetector.java6
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java3
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ColorUsageDetector.java2
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/DuplicateIdDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/FragmentDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/GridLayoutDetector.java2
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/HardcodedDebugModeDetector.java6
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java35
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/JavaPerformanceDetector.java20
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ManifestOrderDetector.java59
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/MergeRootFrameLayoutDetector.java6
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/NestedScrollingWidgetDetector.java2
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/NonInternationalizedSmsDetector.java3
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/OnClickDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/PrivateResourceDetector.java2
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ProguardDetector.java14
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/PxUsageDetector.java8
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/RegistrationDetector.java2
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ScrollViewChildDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/SdCardDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/SecurityDetector.java16
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/SetJavaScriptEnabledDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/SharedPrefsDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/StringFormatDetector.java10
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/TextFieldDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/TextViewDetector.java12
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ToastDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/TooManyViewsDetector.java6
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java8
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java11
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ViewConstructorDetector.java8
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/WakelockDetector.java8
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/WrongIdDetector.java4
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/WrongImportDetector.java15
-rw-r--r--lint/libs/lint_checks/tests/.classpath1
-rw-r--r--lint/libs/lint_checks/tests/Android.mk2
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/XmlReporterTest.java4
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java12
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ManifestOrderDetectorTest.java75
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/missingtarget.xml23
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/oldtarget.xml23
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/client/api/LintClientTest.java29
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/IssueTest.java221
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/LintUtilsTest.java2
-rw-r--r--templates/activities/BlankActivity/root/AndroidManifest.xml.ftl6
-rw-r--r--templates/activities/BlankActivity/root/res/values/strings.xml.ftl2
-rw-r--r--templates/activities/BlankActivity/template.xml4
-rw-r--r--templates/activities/FullscreenActivity/root/AndroidManifest.xml.ftl6
-rw-r--r--templates/activities/FullscreenActivity/root/res/values/strings.xml.ftl2
-rw-r--r--templates/activities/FullscreenActivity/template.xml4
-rw-r--r--templates/activities/LoginActivity/root/AndroidManifest.xml.ftl4
-rw-r--r--templates/activities/LoginActivity/root/res/values/strings.xml.ftl2
-rw-r--r--templates/activities/LoginActivity/template.xml4
-rw-r--r--templates/activities/MasterDetailFlow/root/AndroidManifest.xml.ftl6
-rw-r--r--templates/activities/MasterDetailFlow/root/res/values/strings.xml.ftl2
-rw-r--r--templates/activities/MasterDetailFlow/template.xml4
-rw-r--r--templates/activities/SettingsActivity/root/AndroidManifest.xml.ftl4
-rw-r--r--templates/activities/SettingsActivity/root/res/values/strings.xml.ftl2
-rw-r--r--templates/activities/SettingsActivity/template.xml4
85 files changed, 1000 insertions, 410 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java
index c47cd2d..d690473 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtUtils.java
@@ -16,6 +16,7 @@
package com.android.ide.eclipse.adt;
+import static com.android.tools.lint.detector.api.LintConstants.HIGHEST_KNOWN_API;
import static com.android.tools.lint.detector.api.LintConstants.TOOLS_PREFIX;
import static com.android.tools.lint.detector.api.LintConstants.TOOLS_URI;
@@ -825,6 +826,8 @@ public class AdtUtils {
case 14: return "ICE_CREAM_SANDWICH"; //$NON-NLS-1$
case 15: return "ICE_CREAM_SANDWICH_MR1"; //$NON-NLS-1$
case 16: return "JELLY_BEAN"; //$NON-NLS-1$
+ // If you add more versions here, also update #getAndroidName and
+ // LintConstants#HIGHEST_KNOWN_API
}
return null;
@@ -855,6 +858,9 @@ public class AdtUtils {
case 14: return "API 14: Android 4.0 (IceCreamSandwich)";
case 15: return "API 15: Android 4.0.3 (IceCreamSandwich)";
case 16: return "API 16: Android 4.1 (Jelly Bean)";
+ // If you add more versions here, also update #getBuildCodes and
+ // LintConstants#HIGHEST_KNOWN_API
+
default: {
// Consult SDK manager to see if we know any more (later) names,
// installed by user
@@ -891,7 +897,7 @@ public class AdtUtils {
* @return the highest known API number
*/
public static int getHighestKnownApiLevel() {
- return 16;
+ return HIGHEST_KNOWN_API;
}
/**
@@ -901,7 +907,7 @@ public class AdtUtils {
* maximum known versions (with no gaps)
*/
public static String[] getKnownVersions() {
- int max = 15;
+ int max = getHighestKnownApiLevel();
Sdk sdk = Sdk.getCurrent();
if (sdk != null) {
for (IAndroidTarget target : sdk.getTargets()) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
index 9287787..1e80ce1 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
@@ -68,8 +68,8 @@ import com.android.sdklib.AndroidVersion;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.devices.Device;
import com.android.sdklib.devices.DeviceManager;
-import com.android.sdklib.devices.State;
import com.android.sdklib.devices.DeviceManager.DevicesChangeListener;
+import com.android.sdklib.devices.State;
import com.android.sdklib.internal.avd.AvdInfo;
import com.android.sdklib.internal.avd.AvdManager;
import com.android.sdklib.repository.PkgProps;
@@ -89,6 +89,8 @@ import org.eclipse.jdt.ui.ISharedImages;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
@@ -148,7 +150,7 @@ import java.util.TreeMap;
* loading.<br>
*/
public class ConfigurationComposite extends Composite
- implements SelectionListener, DevicesChangeListener {
+ implements SelectionListener, DevicesChangeListener, DisposeListener {
public static final String ATTR_CONTEXT = "context"; //$NON-NLS-1$
private static final String ICON_SQUARE = "square"; //$NON-NLS-1$
private static final String ICON_LANDSCAPE = "landscape"; //$NON-NLS-1$
@@ -559,6 +561,8 @@ public class ConfigurationComposite extends Composite
addTargetMenuListener(mTargetCombo);
addThemeListener(mThemeCombo);
addOrientationMenuListener(mOrientationCombo);
+
+ addDisposeListener(this);
}
private void updateActivity() {
@@ -568,6 +572,26 @@ public class ConfigurationComposite extends Composite
}
}
+ // ---- Dispose
+
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ dispose();
+ }
+
+ @Override
+ public void dispose() {
+ if (!isDisposed()) {
+ super.dispose();
+
+ final Sdk sdk = Sdk.getCurrent();
+ if (sdk != null) {
+ DeviceManager manager = sdk.getDeviceManager();
+ manager.unregisterListener(this);
+ }
+ }
+ }
+
// ---- Init and reset/reload methods ----
/**
@@ -1885,10 +1909,13 @@ public class ConfigurationComposite extends Composite
devices.add(device);
}
for (List<Device> devices : manufacturers.values()) {
- MenuItem item = new MenuItem(menu, SWT.CASCADE);
- item.setText(devices.get(0).getManufacturer());
- Menu manufacturerMenu = new Menu(menu);
- item.setMenu(manufacturerMenu);
+ Menu manufacturerMenu = menu;
+ if (manufacturers.size() > 1) {
+ MenuItem item = new MenuItem(menu, SWT.CASCADE);
+ item.setText(devices.get(0).getManufacturer());
+ manufacturerMenu = new Menu(menu);
+ item.setMenu(manufacturerMenu);
+ }
for (final Device d : devices) {
MenuItem deviceItem = new MenuItem(manufacturerMenu, SWT.CHECK);
deviceItem.setText(d.getName());
@@ -1904,7 +1931,6 @@ public class ConfigurationComposite extends Composite
});
}
}
-
}
// TODO - how do I dispose of this?
@@ -2675,6 +2701,8 @@ public class ConfigurationComposite extends Composite
if (sdk != null) {
mDeviceList = sdk.getDevices();
DeviceManager manager = sdk.getDeviceManager();
+ // This method can be called more than once, so avoid duplicate entries
+ manager.unregisterListener(this);
manager.registerListener(this);
} else {
mDeviceList = new ArrayList<Device>();
@@ -2698,7 +2726,9 @@ public class ConfigurationComposite extends Composite
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
- addDeviceMenuListener(mDeviceCombo);
+ if (!mDeviceCombo.isDisposed()) {
+ addDeviceMenuListener(mDeviceCombo);
+ }
}
});
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/EclipseLintClient.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/EclipseLintClient.java
index 36ebf5a..350fef1 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/EclipseLintClient.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/EclipseLintClient.java
@@ -29,6 +29,8 @@ import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
+import com.android.ide.eclipse.adt.internal.sdk.Sdk;
+import com.android.sdklib.IAndroidTarget;
import com.android.tools.lint.checks.BuiltinIssueRegistry;
import com.android.tools.lint.client.api.Configuration;
import com.android.tools.lint.client.api.IDomParser;
@@ -577,7 +579,7 @@ public class EclipseLintClient extends LintClient implements IDomParser {
}
String summary = issue.getDescription();
- String explanation = issue.getExplanation();
+ String explanation = issue.getExplanationAsSimpleText();
StringBuilder sb = new StringBuilder(summary.length() + explanation.length() + 20);
try {
@@ -859,6 +861,12 @@ public class EclipseLintClient extends LintClient implements IDomParser {
}
}
+ @Override
+ @NonNull
+ public IAndroidTarget[] getTargets() {
+ return Sdk.getCurrent().getTargets();
+ }
+
private static class LazyLocation extends Location implements Location.Handle {
private final IStructuredDocument mDocument;
private final IndexedRegion mRegion;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFixGenerator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFixGenerator.java
index 5d38df2..97cedc7 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFixGenerator.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFixGenerator.java
@@ -493,7 +493,7 @@ public class LintFixGenerator implements IMarkerResolutionGenerator2, IQuickAssi
sb.append('\n');
if (issue.getExplanation() != null) {
sb.append('\n');
- sb.append(issue.getExplanation());
+ sb.append(issue.getExplanationAsSimpleText());
} else {
sb.append(issue.getDescription());
}
@@ -544,7 +544,9 @@ public class LintFixGenerator implements IMarkerResolutionGenerator2, IQuickAssi
@Override
public String getAdditionalProposalInfo() {
- return "Provides more information about this issue";
+ return "Provides more information about this issue."
+ + "<br><br>" //$NON-NLS-1$
+ + EclipseLintClient.getRegistry().getIssue(mId).getExplanationAsHtml();
}
@Override
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java
index 84f4cf6..d060aff 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java
@@ -56,7 +56,9 @@ import java.util.Set;
*/
public class NewProjectWizard extends TemplateWizard {
private static final String PARENT_ACTIVITY_CLASS = "parentActivityClass"; //$NON-NLS-1$
+ private static final String ACTIVITY_TITLE = "activityTitle"; //$NON-NLS-1$
private static final String IS_LAUNCHER = "isLauncher"; //$NON-NLS-1$
+ static final String IS_NEW_PROJECT = "isNewProject"; //$NON-NLS-1$
static final String ATTR_COPY_ICONS = "copyIcons"; //$NON-NLS-1$
static final String ATTR_TARGET_API = "targetApi"; //$NON-NLS-1$
static final String ATTR_MIN_API = "minApi"; //$NON-NLS-1$
@@ -159,6 +161,7 @@ public class NewProjectWizard extends TemplateWizard {
// Don't ask about hierarchical parent activities in new projects where there
// can't possibly be any
hidden.add(PARENT_ACTIVITY_CLASS);
+ hidden.add(ACTIVITY_TITLE); // Not used for the first activity in the project
mTemplatePage = new NewTemplatePage(activityValues, false);
addPage(mTemplatePage);
@@ -357,6 +360,7 @@ public class NewProjectWizard extends TemplateWizard {
addProjectInfo(parameters);
+ parameters.put(IS_NEW_PROJECT, true);
// Ensure that activities created as part of a new project are marked as
// launcher activities
parameters.put(IS_LAUNCHER, true);
@@ -387,8 +391,10 @@ public class NewProjectWizard extends TemplateWizard {
parameters.put(ATTR_APP_TITLE, mValues.applicationName);
parameters.put(ATTR_MIN_API, mValues.minSdk);
parameters.put(ATTR_MIN_API_LEVEL, mValues.minSdkLevel);
- parameters.put(ATTR_TARGET_API, 15);
- parameters.put(ATTR_BUILD_API, mValues.target.getVersion().getApiLevel());
+ int buildApiLevel = mValues.target.getVersion().getApiLevel();
+ parameters.put(ATTR_BUILD_API, buildApiLevel);
+ parameters.put(ATTR_TARGET_API, buildApiLevel);
+
parameters.put(ATTR_COPY_ICONS, !mValues.createIcon);
parameters.putAll(mValues.parameters);
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java
index 6101161..1d1eb1d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java
@@ -22,6 +22,7 @@ import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectW
import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API_LEVEL;
import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_PACKAGE_NAME;
import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_TARGET_API;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.IS_NEW_PROJECT;
import static com.android.ide.eclipse.adt.internal.wizards.templates.NewTemplateWizard.BLANK_ACTIVITY;
import com.android.annotations.NonNull;
@@ -86,6 +87,7 @@ public class NewTemplateWizardState {
* Create a new state object for use by the {@link NewTemplatePage}
*/
public NewTemplateWizardState() {
+ parameters.put(IS_NEW_PROJECT, false);
}
@NonNull
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
index 2db6b38..16f891f 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
@@ -113,9 +113,11 @@ class TemplateHandler {
* <li> 2: ADT 21 and up. Boolean variables that have a default value and are not
* edited by the user would end up as strings in ADT 20; now they are always
* proper Booleans. Templates which rely on this should specify format >= 2.
+ * <li> 3: The wizard infrastructure passes the {@code isNewProject} boolean variable
+ * to indicate whether a wizard is created as part of a new blank project
* </ul>
*/
- static final int CURRENT_FORMAT = 2;
+ static final int CURRENT_FORMAT = 3;
/**
* Special marker indicating that this path refers to the special shared
diff --git a/lint/cli/.classpath b/lint/cli/.classpath
index b5483f0..fd221d0 100644
--- a/lint/cli/.classpath
+++ b/lint/cli/.classpath
@@ -2,13 +2,14 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry combineaccessrules="false" kind="src" path="/common"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/common"/>
<classpathentry combineaccessrules="false" kind="src" path="/lint-api"/>
<classpathentry combineaccessrules="false" kind="src" path="/lint-checks"/>
- <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/asm-tools/asm-4.0.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/asm-tools/src.zip"/>
- <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/asm-tools/asm-tree-4.0.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/asm-tools/src.zip"/>
+ <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/asm-tools/asm-4.0.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/asm-tools/src.zip"/>
+ <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/asm-tools/asm-tree-4.0.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/asm-tools/src.zip"/>
<classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/asm-tools/asm-analysis-4.0.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/asm-tools/src.zip"/>
- <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/guava-tools/guava-10.0.1.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/guava-tools/src.zip"/>
- <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/lombok-ast/lombok-ast-0.2.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/lombok-ast/src.zip"/>
+ <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/guava-tools/guava-10.0.1.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/guava-tools/src.zip"/>
+ <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/lombok-ast/lombok-ast-0.2.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/lombok-ast/src.zip"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/lint/cli/Android.mk b/lint/cli/Android.mk
index 8a46d48..f762d60 100644
--- a/lint/cli/Android.mk
+++ b/lint/cli/Android.mk
@@ -11,6 +11,7 @@ LOCAL_JAR_MANIFEST := etc/manifest.txt
# If the dependency list is changed, etc/manifest.txt
LOCAL_JAVA_LIBRARIES := \
common \
+ sdklib \
lint_api \
lint_checks \
lombok-ast-0.2 \
diff --git a/lint/cli/etc/manifest.txt b/lint/cli/etc/manifest.txt
index 5f10a7e..f9c95db 100644
--- a/lint/cli/etc/manifest.txt
+++ b/lint/cli/etc/manifest.txt
@@ -1,2 +1,2 @@
Main-Class: com.android.tools.lint.Main
-Class-Path: common.jar layout_lib.jar lint_api.jar lint_checks.jar asm-4.0.jar asm-tree-4.0.jar asm-analysis-4.0.jar guava-10.0.1.jar lombok-ast-0.2.jar
+Class-Path: common.jar layout_lib.jar lint_api.jar lint_checks.jar asm-4.0.jar asm-tree-4.0.jar asm-analysis-4.0.jar guava-10.0.1.jar lombok-ast-0.2.jar sdklib.jar
diff --git a/lint/cli/src/com/android/tools/lint/HtmlReporter.java b/lint/cli/src/com/android/tools/lint/HtmlReporter.java
index c3ed9d2..8fddece 100644
--- a/lint/cli/src/com/android/tools/lint/HtmlReporter.java
+++ b/lint/cli/src/com/android/tools/lint/HtmlReporter.java
@@ -157,9 +157,9 @@ public class HtmlReporter extends Reporter {
mWriter.write("\n<a name=\""); //$NON-NLS-1$
mWriter.write(issue.getCategory().getFullName());
mWriter.write("\"></a>\n"); //$NON-NLS-1$
- mWriter.write("<div class=\"category\">"); //$NON-NLS-1$
+ mWriter.write("<div class=\"category\"><a href=\"#\" title=\"Return to top\">"); //$NON-NLS-1$
mWriter.write(issue.getCategory().getFullName());
- mWriter.write("<div class=\"categorySeparator\"></div>\n");//$NON-NLS-1$
+ mWriter.write("</a><div class=\"categorySeparator\"></div>\n");//$NON-NLS-1$
mWriter.write("</div>\n"); //$NON-NLS-1$
}
@@ -167,9 +167,9 @@ public class HtmlReporter extends Reporter {
mWriter.write("<div class=\"issue\">\n"); //$NON-NLS-1$
// Explain this issue
- mWriter.write("<div class=\"id\">"); //$NON-NLS-1$
+ mWriter.write("<div class=\"id\"><a href=\"#\" title=\"Return to top\">"); //$NON-NLS-1$
mWriter.write(issue.getId());
- mWriter.write("<div class=\"issueSeparator\"></div>\n"); //$NON-NLS-1$
+ mWriter.write("</a><div class=\"issueSeparator\"></div>\n"); //$NON-NLS-1$
mWriter.write("</div>\n"); //$NON-NLS-1$
mWriter.write("<div class=\"warningslist\">\n"); //$NON-NLS-1$
@@ -368,8 +368,8 @@ public class HtmlReporter extends Reporter {
}
mWriter.write("</div>\n"); //$NON-NLS-1$
mWriter.write("<div class=\"explanation\">\n"); //$NON-NLS-1$
- String explanation = issue.getExplanation();
- appendEscapedText(explanation, true /* preserve newlines*/);
+ String explanationHtml = issue.getExplanationAsHtml();
+ mWriter.write(explanationHtml);
mWriter.write("\n</div>\n"); //$NON-NLS-1$;
if (issue.getMoreInfo() != null) {
mWriter.write("<br/>"); //$NON-NLS-1$
@@ -400,7 +400,7 @@ public class HtmlReporter extends Reporter {
mWriter.write("Suppressing Warnings and Errors");
mWriter.write("<div class=\"categorySeparator\"></div>\n");//$NON-NLS-1$
mWriter.write("</div>\n"); //$NON-NLS-1$
- appendEscapedText(Main.getSuppressHelp(), true /* preserve newlines*/);
+ appendEscapedText(Main.getSuppressHelp());
mWriter.write('\n');
}
@@ -725,10 +725,6 @@ public class HtmlReporter extends Reporter {
}
private void appendEscapedText(String textValue) throws IOException {
- appendEscapedText(textValue, false);
- }
-
- private void appendEscapedText(String textValue, boolean preserveNewlines) throws IOException {
for (int i = 0, n = textValue.length(); i < n; i++) {
char c = textValue.charAt(i);
if (c == '<') {
diff --git a/lint/cli/src/com/android/tools/lint/hololike.css b/lint/cli/src/com/android/tools/lint/hololike.css
index 5c0080c..b12611f 100644
--- a/lint/cli/src/com/android/tools/lint/hololike.css
+++ b/lint/cli/src/com/android/tools/lint/hololike.css
@@ -24,6 +24,13 @@ body {
.explanation {
margin-top: 10px;
}
+.explanation b {
+ color: #ffbbbb;
+}
+.explanation code {
+ color: #bebebe;
+ font-family: 'Roboto', Sans-Serif;
+}
pre {
background-color: #282828;
margin: 5px 0px 5px 5px;
@@ -124,6 +131,38 @@ a:active {
.issue a:visited {
text-decoration: underline;
}
+.id a:link {
+ text-decoration: none;
+ color: #bebebe;
+}
+.id a:visited {
+ text-decoration: none;
+ color: #bebebe;
+}
+.id a:hover {
+ text-decoration: underline;
+ color: #f3f3f3;
+}
+.id a:active {
+ text-decoration: underline;
+ color: #bebebe;
+}
+.category a:link {
+ text-decoration: none;
+ color: #bebebe;
+}
+.category a:visited {
+ text-decoration: none;
+ color: #bebebe;
+}
+.category a:hover {
+ text-decoration: underline;
+ color: #f3f3f3;
+}
+.category a:active {
+ text-decoration: underline;
+ color: #bebebe;
+}
button {
color: #ffffff;
background-color: #353535;
@@ -133,4 +172,4 @@ button {
border-top: solid 1px #5b5b5b;
font-family: 'Roboto', Sans-Serif;
font-size: 12pt;
-} \ No newline at end of file
+}
diff --git a/lint/libs/lint_api/.classpath b/lint/libs/lint_api/.classpath
index f52ce2f..39495cc 100644
--- a/lint/libs/lint_api/.classpath
+++ b/lint/libs/lint_api/.classpath
@@ -8,5 +8,6 @@
<classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/guava-tools/guava-10.0.1.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/guava-tools/src.zip"/>
<classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/lombok-ast/lombok-ast-0.2.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/lombok-ast/src.zip"/>
<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_api"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/lint/libs/lint_api/Android.mk b/lint/libs/lint_api/Android.mk
index d6d26f3..9e2e678 100644
--- a/lint/libs/lint_api/Android.mk
+++ b/lint/libs/lint_api/Android.mk
@@ -22,6 +22,7 @@ LOCAL_JAVA_RESOURCE_DIRS := src
LOCAL_JAVA_LIBRARIES := \
lombok-ast-0.2 \
common \
+ sdklib \
layoutlib_api \
asm-tools \
asm-tree-tools \
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java
index f168d7a..363b9cd 100644
--- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java
+++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java
@@ -24,13 +24,18 @@ import static com.android.tools.lint.detector.api.LintConstants.SRC_FOLDER;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkManager;
import com.android.tools.lint.detector.api.Context;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.LintConstants;
import com.android.tools.lint.detector.api.LintUtils;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.Project;
import com.android.tools.lint.detector.api.Severity;
+import com.android.utils.StdLogger;
+import com.android.utils.StdLogger.Level;
import com.google.common.annotations.Beta;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
@@ -285,6 +290,32 @@ public abstract class LintClient {
}
/**
+ * Returns the File pointing to the user's SDK install area. This is generally
+ * the root directory containing the lint tool (but also platforms/ etc).
+ *
+ * @return a file pointing to the user's install area
+ */
+ @Nullable
+ public File getSdkHome() {
+ File binDir = getLintBinDir();
+ if (binDir != null) {
+ assert binDir.getName().equals("tools");
+
+ File root = binDir.getParentFile();
+ if (root != null && root.isDirectory()) {
+ return root;
+ }
+ }
+
+ String home = System.getenv("ANDROID_HOME"); //$NON-NLS-1$
+ if (home != null) {
+ return new File(home);
+ }
+
+ return null;
+ }
+
+ /**
* Locates an SDK resource (relative to the SDK root directory).
* <p>
* TODO: Consider switching to a {@link URL} return type instead.
@@ -524,4 +555,48 @@ public abstract class LintClient {
mDirToProject.put(canonicalDir, project);
return project;
}
+
+ private IAndroidTarget[] mTargets;
+
+ /**
+ * Returns all the {@link IAndroidTarget} versions installed in the user's SDK install
+ * area.
+ *
+ * @return all the installed targets
+ */
+ @NonNull
+ public IAndroidTarget[] getTargets() {
+ if (mTargets == null) {
+ File sdkHome = getSdkHome();
+ if (sdkHome != null) {
+ StdLogger log = new StdLogger(Level.WARNING);
+ SdkManager manager = SdkManager.createManager(sdkHome.getPath(), log);
+ mTargets = manager.getTargets();
+ } else {
+ mTargets = new IAndroidTarget[0];
+ }
+ }
+
+ return mTargets;
+ }
+
+ /**
+ * Returns the highest known API level.
+ *
+ * @return the highest known API level
+ */
+ public int getHighestKnownApiLevel() {
+ int max = LintConstants.HIGHEST_KNOWN_API;
+
+ for (IAndroidTarget target : getTargets()) {
+ if (target.isPlatform()) {
+ int api = target.getVersion().getApiLevel();
+ if (api > max && !target.getVersion().isPreview()) {
+ max = api;
+ }
+ }
+ }
+
+ return max;
+ }
}
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 d91b155..8ff5fc0 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
@@ -34,6 +34,7 @@ import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.annotations.VisibleForTesting;
import com.android.resources.ResourceFolderType;
+import com.android.sdklib.IAndroidTarget;
import com.android.tools.lint.client.api.LintListener.EventType;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.ClassContext;
@@ -1650,6 +1651,41 @@ public class LintDriver {
public File findResource(@NonNull String relativePath) {
return mDelegate.findResource(relativePath);
}
+
+ @Override
+ @Nullable
+ public File getCacheDir(boolean create) {
+ return mDelegate.getCacheDir(create);
+ }
+
+ @Override
+ @NonNull
+ protected ClassPathInfo getClassPath(@NonNull Project project) {
+ return mDelegate.getClassPath(project);
+ }
+
+ @Override
+ public void log(@Nullable Throwable exception, @Nullable String format,
+ @Nullable Object... args) {
+ mDelegate.log(exception, format, args);
+ }
+
+ @Override
+ @Nullable
+ public File getSdkHome() {
+ return mDelegate.getSdkHome();
+ }
+
+ @Override
+ @NonNull
+ public IAndroidTarget[] getTargets() {
+ return mDelegate.getTargets();
+ }
+
+ @Override
+ public int getHighestKnownApiLevel() {
+ return mDelegate.getHighestKnownApiLevel();
+ }
}
/**
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Issue.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Issue.java
index 1ac15e2..70d3cf7 100644
--- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Issue.java
+++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Issue.java
@@ -42,6 +42,8 @@ import java.util.List;
*/
@Beta
public final class Issue implements Comparable<Issue> {
+ private static final String HTTP_PREFIX = "http://"; //$NON-NLS-1$
+
private final String mId;
private final String mDescription;
private final String mExplanation;
@@ -131,6 +133,12 @@ public final class Issue implements Comparable<Issue> {
* "Buttons must define contentDescriptions". Preferably the explanation
* should also contain a description of how the problem should be solved.
* Additional info can be provided via {@link #getMoreInfo()}.
+ * <p>
+ * Note that the text may contain some simple markup, such as *'s around sentences
+ * for bold text, and back quotes (`) for code fragments. You can obtain
+ * the text without this markup by calling {@link #getExplanationAsSimpleText()},
+ * and you can obtain the text as annotated HTML by calling
+ * {@link #getExplanationAsHtml()}.
*
* @return an explanation of the issue, never null.
*/
@@ -140,6 +148,30 @@ public final class Issue implements Comparable<Issue> {
}
/**
+ * Like {@link #getExplanation()}, but returns the text as properly escaped
+ * and marked up HTML, where http URLs are linked, where words with asterisks
+ * such as *this* are shown in bold, etc.
+ *
+ * @return the explanation of the issue, never null
+ */
+ @NonNull
+ public String getExplanationAsHtml() {
+ return convertMarkup(mExplanation, true /* html */);
+ }
+
+ /**
+ * Like {@link #getExplanation()}, but returns the text as properly escaped
+ * and marked up HTML, where http URLs are linked, where words with asterisks
+ * such as *this* are shown in bold, etc.
+ *
+ * @return the explanation of the issue, never null
+ */
+ @NonNull
+ public String getExplanationAsSimpleText() {
+ return convertMarkup(mExplanation, false /* not html = text */);
+ }
+
+ /**
* The primary category of the issue
*
* @return the primary category of the issue, never null
@@ -395,4 +427,126 @@ public final class Issue implements Comparable<Issue> {
public String toString() {
return mId;
}
+
+ /**
+ * Converts the given markup text to HTML or text, depending on the.
+ * <p>
+ * This will recognize the following formatting conventions:
+ * <ul>
+ * <li>HTTP urls (http://...)
+ * <li>Sentences immediately surrounded by * will be shown as bold.
+ * <li>Sentences immediately surrounded by ` will be shown using monospace
+ * fonts
+ * </ul>
+ * Furthermore, newlines are converted to br's when converting newlines.
+ * Note: It does not insert {@code <html>} tags around the fragment for HTML output.
+ * <p>
+ * TODO: Consider switching to the restructured text format -
+ * http://docutils.sourceforge.net/docs/user/rst/quickstart.html
+ *
+ * @param text the text to be formatted
+ * @param html whether to convert into HTML or text
+ * @return the corresponding HTML or text properly formatted
+ */
+ @NonNull
+ public static String convertMarkup(@NonNull String text, boolean html) {
+ StringBuilder sb = new StringBuilder(3 * text.length() / 2);
+
+ char prev = 0;
+ int flushIndex = 0;
+ int n = text.length();
+ for (int i = 0; i < n; i++) {
+ char c = text.charAt(i);
+ if ((c == '*' || c == '`' && i < n - 1)) {
+ // Scout ahead for range end
+ if (!Character.isLetterOrDigit(prev)
+ && !Character.isWhitespace(text.charAt(i + 1))) {
+ // Found * or ~ immediately before a letter, and not in the middle of a word
+ // Find end
+ int end = text.indexOf(c, i + 1);
+ if (end != -1 && (end == n - 1 || !Character.isLetter(text.charAt(end + 1)))) {
+ if (i > flushIndex) {
+ appendEscapedText(sb, text, html, flushIndex, i);
+ }
+ if (html) {
+ String tag = c == '*' ? "b" : "code"; //$NON-NLS-1$ //$NON-NLS-2$
+ sb.append('<').append(tag).append('>');
+ appendEscapedText(sb, text, html, i + 1, end);
+ sb.append('<').append('/').append(tag).append('>');
+ } else {
+ appendEscapedText(sb, text, html, i + 1, end);
+ }
+ flushIndex = end + 1;
+ i = flushIndex - 1; // -1: account for the i++ in the loop
+ }
+ }
+ } else if (html && c == 'h' && i < n - 1 && text.charAt(i + 1) == 't'
+ && text.startsWith(HTTP_PREFIX, i) && !Character.isLetterOrDigit(prev)) {
+ // Find url end
+ int end = i + HTTP_PREFIX.length();
+ while (end < n) {
+ char d = text.charAt(end);
+ if (Character.isWhitespace(d)) {
+ break;
+ }
+ end++;
+ }
+ char last = text.charAt(end - 1);
+ if (last == '.' || last == ')' || last == '!') {
+ end--;
+ }
+ if (end > i + HTTP_PREFIX.length()) {
+ if (i > flushIndex) {
+ appendEscapedText(sb, text, html, flushIndex, i);
+ }
+
+ String url = text.substring(i, end);
+ sb.append("<a href=\""); //$NON-NLS-1$
+ sb.append(url);
+ sb.append('"').append('>');
+ sb.append(url);
+ sb.append("</a>"); //$NON-NLS-1$
+
+ flushIndex = end;
+ i = flushIndex - 1; // -1: account for the i++ in the loop
+ }
+ }
+ prev = c;
+ }
+
+ if (flushIndex < n) {
+ appendEscapedText(sb, text, html, flushIndex, n);
+ }
+
+ return sb.toString();
+ }
+
+ static void appendEscapedText(StringBuilder sb, String text, boolean html,
+ int start, int end) {
+ if (html) {
+ for (int i = start; i < end; i++) {
+ char c = text.charAt(i);
+ if (c == '<') {
+ sb.append("&lt;"); //$NON-NLS-1$
+ } else if (c == '&') {
+ sb.append("&amp;"); //$NON-NLS-1$
+ } else if (c == '\n') {
+ sb.append("<br/>\n");
+ } else {
+ if (c > 255) {
+ sb.append("&#"); //$NON-NLS-1$
+ sb.append(Integer.toString(c));
+ sb.append(';');
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ } else {
+ for (int i = start; i < end; i++) {
+ char c = text.charAt(i);
+ sb.append(c);
+ }
+ }
+ }
}
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 a0ff760..40b468d 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
@@ -341,4 +341,13 @@ public class LintConstants {
"android/content/ContentProvider"; //$NON-NLS-1$
public static final String ANDROID_CONTENT_BROADCAST_RECEIVER =
"android/content/BroadcastReceiver"; //$NON-NLS-1$
+
+ /**
+ * The highest known API level. Note that the tools may also look at the
+ * installed platforms to see if they can find more recently released
+ * platforms, e.g. when the tools have not yet been updated for a new
+ * release. This number is used as a baseline and any more recent platforms
+ * found can be used to increase the highest known number.
+ */
+ public static final int HIGHEST_KNOWN_API = 16;
}
diff --git a/lint/libs/lint_checks/.classpath b/lint/libs/lint_checks/.classpath
index 1316db4..4a48734 100644
--- a/lint/libs/lint_checks/.classpath
+++ b/lint/libs/lint_checks/.classpath
@@ -10,5 +10,6 @@
<classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/lombok-ast/lombok-ast-0.2.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/lombok-ast/src.zip"/>
<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_api"/>
<classpathentry combineaccessrules="false" kind="src" path="/common"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/lint/libs/lint_checks/Android.mk b/lint/libs/lint_checks/Android.mk
index a5ed601..e15e928 100644
--- a/lint/libs/lint_checks/Android.mk
+++ b/lint/libs/lint_checks/Android.mk
@@ -7,11 +7,10 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_RESOURCE_DIRS := src
-LOCAL_JAR_MANIFEST := etc/manifest.txt
-
# If the dependency list is changed, etc/manifest.txt
LOCAL_JAVA_LIBRARIES := \
common \
+ sdklib \
layoutlib_api \
lombok-ast-0.2 \
lint_api \
diff --git a/lint/libs/lint_checks/NOTICE b/lint/libs/lint_checks/NOTICE
deleted file mode 100644
index becc120..0000000
--- a/lint/libs/lint_checks/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2011, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/lint/libs/lint_checks/etc/manifest.txt b/lint/libs/lint_checks/etc/manifest.txt
deleted file mode 100644
index 36cee35..0000000
--- a/lint/libs/lint_checks/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Class-Path: lint_api.jar common.jar layoutlib_api.jar
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/AccessibilityDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/AccessibilityDetector.java
index e1be383..af5c805 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/AccessibilityDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/AccessibilityDetector.java
@@ -51,7 +51,7 @@ public class AccessibilityDetector extends LayoutDetector {
"ContentDescription", //$NON-NLS-1$
"Ensures that image widgets provide a contentDescription",
"Non-textual widgets like ImageViews and ImageButtons should use the " +
- "contentDescription attribute to specify a textual description of " +
+ "`contentDescription` attribute to specify a textual description of " +
"the widget such that screen readers and other accessibility tools " +
"can adequately describe the user interface.",
Category.A11Y,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/AlwaysShowActionDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/AlwaysShowActionDetector.java
index bc5eaae..42d48bc 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/AlwaysShowActionDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/AlwaysShowActionDetector.java
@@ -61,18 +61,18 @@ public class AlwaysShowActionDetector extends ResourceXmlDetector implements Jav
"Checks for uses of showAsAction=\"always\" and suggests showAsAction=\"ifRoom\" " +
"instead",
- "Using showAsAction=\"always\" in menu XML, or MenuItem.SHOW_AS_ACTION_ALWAYS in " +
+ "Using `showAsAction=\"always\"` in menu XML, or `MenuItem.SHOW_AS_ACTION_ALWAYS` in " +
"Java code is usually a deviation from the user interface style guide." +
- "Use \"ifRoom\" or the corresponding MenuItem.SHOW_AS_ACTION_IF_ROOM instead.\n" +
+ "Use `ifRoom` or the corresponding `MenuItem.SHOW_AS_ACTION_IF_ROOM` instead.\n" +
"\n" +
- "If \"always\" is used sparingly there are usually no problems and behavior is " +
- "roughly equivalent to \"ifRoom\" but with preference over other \"ifRoom\" " +
+ "If `always` is used sparingly there are usually no problems and behavior is " +
+ "roughly equivalent to `ifRoom` but with preference over other `ifRoom` " +
"items. Using it more than twice in the same menu is a bad idea.\n" +
"\n" +
- "This check looks for menu XML files that contain more than two \"always\" " +
- "actions, or some \"always\" actions and no \"ifRoom\" actions. In Java code, " +
- "it looks for projects that contain references to MenuItem.SHOW_AS_ACTION_ALWAYS " +
- "and no references to MenuItem.SHOW_AS_ACTION_IF_ROOM.",
+ "This check looks for menu XML files that contain more than two `always` " +
+ "actions, or some `always` actions and no `ifRoom` actions. In Java code, " +
+ "it looks for projects that contain references to `MenuItem.SHOW_AS_ACTION_ALWAYS` " +
+ "and no references to `MenuItem.SHOW_AS_ACTION_IF_ROOM`.",
Category.USABILITY,
3,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/AnnotationDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/AnnotationDetector.java
index aa0c84d..0cb145e 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/AnnotationDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/AnnotationDetector.java
@@ -57,10 +57,10 @@ public class AnnotationDetector extends Detector implements Detector.JavaScanner
"LocalSuppress", //$NON-NLS-1$
"Looks for @SuppressLint annotations in locations where it doesn't work for class based checks",
- "The @SuppressAnnotation is used to suppress Lint warnings in Java files. However, " +
+ "The `@SuppressAnnotation` is used to suppress Lint warnings in Java files. However, " +
"while many lint checks analyzes the Java source code, where they can find " +
"annotations on (for example) local variables, some checks are analyzing the " +
- ".class files. And in class files, annotations only appear on classes, fields " +
+ "`.class` files. And in class files, annotations only appear on classes, fields " +
"and methods. Annotations placed on local variables disappear. If you attempt " +
"to suppress a lint error for a class-file based lint check, the suppress " +
"annotation not work. You must move the annotation out to the surrounding method.",
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiDetector.java
index 8762a0c..1643e58 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiDetector.java
@@ -79,13 +79,13 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc
"by this application (according to its minimum SDK attribute in the manifest).\n" +
"\n" +
"If you really want to use this API and don't need to support older devices just " +
- "set the minSdkVersion in your AndroidManifest.xml file." +
+ "set the `minSdkVersion` in your `AndroidManifest.xml` file." +
"\n" +
"If your code is *deliberately* accessing newer APIs, and you have ensured " +
"(e.g. with conditional execution) that this code will only ever be called on a " +
"supported platform, then you can annotate your class or method with the " +
- "@TargetApi annotation specifying the local minimum SDK to apply, such as" +
- "@TargetApi(11), such that this check considers 11 rather than your manifest " +
+ "`@TargetApi` annotation specifying the local minimum SDK to apply, such as " +
+ "`@TargetApi(11)`, such that this check considers 11 rather than your manifest " +
"file's minimum SDK as the required API level.",
Category.CORRECTNESS,
6,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java
index dd1e973..e1325b5 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java
@@ -54,7 +54,7 @@ public class BuiltinIssueRegistry extends IssueRegistry {
private static final List<Issue> sIssues;
static {
- final int initialCapacity = 101;
+ final int initialCapacity = 102;
List<Issue> issues = new ArrayList<Issue>(initialCapacity);
issues.add(AccessibilityDetector.ISSUE);
@@ -109,6 +109,7 @@ public class BuiltinIssueRegistry extends IssueRegistry {
issues.add(ManifestOrderDetector.MULTIPLE_USES_SDK);
issues.add(ManifestOrderDetector.WRONG_PARENT);
issues.add(ManifestOrderDetector.DUPLICATE_ACTIVITY);
+ issues.add(ManifestOrderDetector.TARGET_NEWER);
issues.add(SecurityDetector.EXPORTED_PROVIDER);
issues.add(SecurityDetector.EXPORTED_SERVICE);
issues.add(SecurityDetector.EXPORTED_ACTIVITY);
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ColorUsageDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ColorUsageDetector.java
index dc3410b..2c7a520 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ColorUsageDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ColorUsageDetector.java
@@ -49,7 +49,7 @@ public class ColorUsageDetector extends Detector implements Detector.JavaScanner
"Methods that take a color in the form of an integer should be passed " +
"an RGB triple, not the actual color resource id. You must call " +
- "getResources().getColor(resource) to resolve the actual color value first.",
+ "`getResources().getColor(resource)` to resolve the actual color value first.",
Category.CORRECTNESS,
7,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/DuplicateIdDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/DuplicateIdDetector.java
index c8e34c5..f27005c 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/DuplicateIdDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/DuplicateIdDetector.java
@@ -76,7 +76,7 @@ public class DuplicateIdDetector extends LayoutDetector {
public static final Issue WITHIN_LAYOUT = Issue.create(
"DuplicateIds", //$NON-NLS-1$
"Checks for duplicate ids within a single layout",
- "Within a layout, id's should be unique since otherwise findViewById() can " +
+ "Within a layout, id's should be unique since otherwise `findViewById()` can " +
"return an unexpected view.",
Category.CORRECTNESS,
7,
@@ -90,7 +90,7 @@ public class DuplicateIdDetector extends LayoutDetector {
"Checks for duplicate ids across layouts that are combined with include tags",
"It's okay for two independent layouts to use the same ids. However, if " +
"layouts are combined with include tags, then the id's need to be unique " +
- "within any chain of included layouts, or Activity#findViewById() can " +
+ "within any chain of included layouts, or `Activity#findViewById()` can " +
"return an unexpected view.",
Category.CORRECTNESS,
6,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/FragmentDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/FragmentDetector.java
index 2fc3034..06162c4 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/FragmentDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/FragmentDetector.java
@@ -60,8 +60,8 @@ public class FragmentDetector extends Detector implements ClassScanner {
"restoring its activity's state. It is strongly recommended that subclasses do not " +
"have other constructors with parameters, since these constructors will not be " +
"called when the fragment is re-instantiated; instead, arguments can be supplied " +
- "by the caller with setArguments(Bundle) and later retrieved by the Fragment " +
- "with getArguments().",
+ "by the caller with `setArguments(Bundle)` and later retrieved by the Fragment " +
+ "with `getArguments()`.",
Category.CORRECTNESS,
6,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/GridLayoutDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/GridLayoutDetector.java
index 6e8d8a3..f32905a 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/GridLayoutDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/GridLayoutDetector.java
@@ -49,7 +49,7 @@ public class GridLayoutDetector extends LayoutDetector {
"Checks for potential GridLayout errors like declaring rows and columns outside " +
"the declared grid dimensions",
"Declaring a layout_row or layout_column that falls outside the declared size " +
- "of a GridLayout's rowCount or columnCount is usually an unintentional error.",
+ "of a GridLayout's `rowCount` or `columnCount` is usually an unintentional error.",
Category.CORRECTNESS,
4,
Severity.FATAL,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/HardcodedDebugModeDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/HardcodedDebugModeDetector.java
index 1237e1b..b684e6f 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/HardcodedDebugModeDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/HardcodedDebugModeDetector.java
@@ -46,10 +46,10 @@ public class HardcodedDebugModeDetector extends Detector implements Detector.Xml
"HardcodedDebugMode", //$NON-NLS-1$
"Checks for hardcoded values of android:debuggable in the manifest",
- "It's best to leave out the android:debuggable attribute from the manifest. " +
- "If you do, then the tools will automatically insert android:debuggable=true when " +
+ "It's best to leave out the `android:debuggable` attribute from the manifest. " +
+ "If you do, then the tools will automatically insert `android:debuggable=true` when " +
"building an APK to debug on an emulator or device. And when you perform a " +
- "release build, such as Exporting APK, it will automatically set it to false.\n" +
+ "release build, such as Exporting APK, it will automatically set it to `false`.\n" +
"\n" +
"If on the other hand you specify a specific value in the manifest file, then " +
"the tools will always use it. This can lead to accidentally publishing " +
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java
index da27cc9..9dd42b9 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java
@@ -129,7 +129,7 @@ public class IconDetector extends Detector implements Detector.XmlScanner {
"IconDipSize", //$NON-NLS-1$
"Ensures that icons across densities provide roughly the same density-independent size",
"Checks the all icons which are provided in multiple densities, all compute to " +
- "roughly the same density-independent pixel (dip) size. This catches errors where " +
+ "roughly the same density-independent pixel (`dip`) size. This catches errors where " +
"images are either placed in the wrong folder, or icons are changed to new sizes " +
"but some folders are forgotten.",
Category.ICONS,
@@ -143,10 +143,10 @@ public class IconDetector extends Detector implements Detector.XmlScanner {
"IconLocation", //$NON-NLS-1$
"Ensures that images are not defined in the density-independent drawable folder",
"The res/drawable folder is intended for density-independent graphics such as " +
- "shapes defined in XML. For bitmaps, move it to drawable-mdpi and consider " +
- "providing higher and lower resolution versions in drawable-ldpi, drawable-hdpi " +
- "and drawable-xhdpi. If the icon *really* is density independent (for example " +
- "a solid color) you can place it in drawable-nodpi.",
+ "shapes defined in XML. For bitmaps, move it to `drawable-mdpi` and consider " +
+ "providing higher and lower resolution versions in `drawable-ldpi`, `drawable-hdpi` " +
+ "and `drawable-xhdpi`. If the icon *really* is density independent (for example " +
+ "a solid color) you can place it in `drawable-nodpi`.",
Category.ICONS,
5,
Severity.WARNING,
@@ -165,7 +165,7 @@ public class IconDetector extends Detector implements Detector.XmlScanner {
"\n" +
"Low density is not really used much anymore, so this check ignores " +
"the ldpi density. To force lint to include it, set the environment " +
- "variable ANDROID_LINT_INCLUDE_LDPI=true. For more information on " +
+ "variable `ANDROID_LINT_INCLUDE_LDPI=true`. For more information on " +
"current density usage, see " +
"http://developer.android.com/resources/dashboard/screens.html",
Category.ICONS,
@@ -181,11 +181,11 @@ public class IconDetector extends Detector implements Detector.XmlScanner {
"Ensures that all the density folders are present",
"Icons will look best if a custom version is provided for each of the " +
"major screen density classes (low, medium, high, extra high). " +
- "This lint check identifies folders which are missing, such as drawable-hdpi." +
+ "This lint check identifies folders which are missing, such as `drawable-hdpi`." +
"\n" +
"Low density is not really used much anymore, so this check ignores " +
"the ldpi density. To force lint to include it, set the environment " +
- "variable ANDROID_LINT_INCLUDE_LDPI=true. For more information on " +
+ "variable `ANDROID_LINT_INCLUDE_LDPI=true`. For more information on " +
"current density usage, see " +
"http://developer.android.com/resources/dashboard/screens.html",
Category.ICONS,
@@ -199,8 +199,8 @@ public class IconDetector extends Detector implements Detector.XmlScanner {
public static final Issue GIF_USAGE = Issue.create(
"GifUsage", //$NON-NLS-1$
"Checks for images using the GIF file format which is discouraged",
- "The .gif file format is discouraged. Consider using .png (preferred) " +
- "or .jpg (acceptable) instead.",
+ "The `.gif` file format is discouraged. Consider using `.png` (preferred) " +
+ "or `.jpg` (acceptable) instead.",
Category.ICONS,
5,
Severity.WARNING,
@@ -227,7 +227,7 @@ public class IconDetector extends Detector implements Detector.XmlScanner {
"IconDuplicatesConfig", //$NON-NLS-1$
"Finds icons that have identical bitmaps across various configuration parameters",
"If an icon is provided under different configuration parameters such as " +
- "drawable-hdpi or -v11, they should typically be different. This detector " +
+ "`drawable-hdpi` or `-v11`, they should typically be different. This detector " +
"catches cases where the same icon is provided in different configuration folder " +
"which is usually not intentional.",
Category.ICONS,
@@ -240,9 +240,9 @@ public class IconDetector extends Detector implements Detector.XmlScanner {
public static final Issue ICON_NODPI = Issue.create(
"IconNoDpi", //$NON-NLS-1$
"Finds icons that appear in both a -nodpi folder and a dpi folder",
- "Bitmaps that appear in drawable-nodpi folders will not be scaled by the " +
+ "Bitmaps that appear in `drawable-nodpi` folders will not be scaled by the " +
"Android framework. If a drawable resource of the same name appears *both* in " +
- "a -nodpi folder as well as a dpi folder such as drawable-hdpi, then " +
+ "a `-nodpi` folder as well as a dpi folder such as `drawable-hdpi`, then " +
"the behavior is ambiguous and probably not intentional. Delete one or the " +
"other, or use different names for the icons.",
Category.ICONS,
@@ -1049,8 +1049,13 @@ public class IconDetector extends Detector implements Detector.XmlScanner {
checkSize(context, folderName, file, 25, 25, true /*exact*/);
}
} else if (name.startsWith("ic_menu_")) { //$NON-NLS-1$
- // Menu icons (<=2.3 only: Replaced by action bar icons (ic_action_ in 3.0).
- if (isAndroid23(context, folderVersion)) {
+ if (isAndroid30(context, folderVersion)) {
+ // Menu icons (<=2.3 only: Replaced by action bar icons (ic_action_ in 3.0).
+ // However the table halfway down the page on
+ // http://developer.android.com/guide/practices/ui_guidelines/icon_design.html
+ // and the README in the icon template download says that convention is ic_menu
+ checkSize(context, folderName, file, 32, 32, true);
+ } else if (isAndroid23(context, folderVersion)) {
// The icon should be 32x32 inside the transparent image; should
// we check that this is mostly the case (a few pixels are allowed to
// overlap for anti-aliasing etc)
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java
index 3fd5573..c00b57e 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java
@@ -55,8 +55,8 @@ public class InefficientWeightDetector extends LayoutDetector {
"InefficientWeight", //$NON-NLS-1$
"Looks for inefficient weight declarations in LinearLayouts",
"When only a single widget in a LinearLayout defines a weight, it is more " +
- "efficient to assign a width/height of 0dp to it since it will absorb all " +
- "the remaining space anyway. With a declared width/height of 0dp it " +
+ "efficient to assign a width/height of `0dp` to it since it will absorb all " +
+ "the remaining space anyway. With a declared width/height of `0dp` it " +
"does not have to measure its own size first.",
Category.PERFORMANCE,
3,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/JavaPerformanceDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/JavaPerformanceDetector.java
index 0073d06..fe3b713 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/JavaPerformanceDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/JavaPerformanceDetector.java
@@ -72,7 +72,7 @@ public class JavaPerformanceDetector extends Detector implements Detector.JavaSc
"The way this is generally handled is to allocate the needed objects up front " +
"and to reuse them for each drawing operation.\n" +
"\n" +
- "Some methods allocate memory on your behalf (such as Bitmap.create), and these " +
+ "Some methods allocate memory on your behalf (such as `Bitmap.create`), and these " +
"should be handled in the same way.",
Category.PERFORMANCE,
@@ -87,16 +87,16 @@ public class JavaPerformanceDetector extends Detector implements Detector.JavaSc
"Looks for opportunities to replace HashMaps with the more efficient SparseArray",
"For maps where the keys are of type integer, it's typically more efficient to " +
- "use the Android SparseArray API. This check identifies scenarios where you might " +
- "want to consider using SparseArray instead of HashMap for better performance.\n" +
+ "use the Android `SparseArray` API. This check identifies scenarios where you might " +
+ "want to consider using `SparseArray` instead of `HashMap` for better performance.\n" +
"\n" +
"This is *particularly* useful when the value types are primitives like ints, " +
- "where you can use SparseIntArray and avoid auto-boxing the values from int to " +
- "Integer.\n" +
+ "where you can use `SparseIntArray` and avoid auto-boxing the values from `int` to " +
+ "`Integer`.\n" +
"\n" +
- "If you need to construct a HashMap because you need to call an API outside of " +
- "your control which requires a Map, you can suppress this warning using for " +
- "example the @SuppressLint annotation.",
+ "If you need to construct a `HashMap` because you need to call an API outside of " +
+ "your control which requires a `Map`, you can suppress this warning using for " +
+ "example the `@SuppressLint` annotation.",
Category.PERFORMANCE,
4,
@@ -110,8 +110,8 @@ public class JavaPerformanceDetector extends Detector implements Detector.JavaSc
"Looks for usages of \"new\" for wrapper classes which should use \"valueOf\" instead",
"You should not call the constructor for wrapper classes directly, such as" +
- "\"new Integer(42)\". Instead, call the \"valueOf\" factory method, such as " +
- "Integer.valueOf(42). This will typically use less memory because common integers " +
+ "`new Integer(42)`. Instead, call the `valueOf` factory method, such as " +
+ "`Integer.valueOf(42)`. This will typically use less memory because common integers " +
"such as 0 and 1 will share a single instance.",
Category.PERFORMANCE,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ManifestOrderDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ManifestOrderDetector.java
index b116eb9..44553fa 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ManifestOrderDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ManifestOrderDetector.java
@@ -67,7 +67,7 @@ public class ManifestOrderDetector extends Detector implements Detector.XmlScann
"The <application> tag should appear after the elements which declare " +
"which version you need, which features you need, which libraries you " +
"need, and so on. In the past there have been subtle bugs (such as " +
- "themes not getting applied correctly) when the <application> tag appears " +
+ "themes not getting applied correctly) when the `<application>` tag appears " +
"before some of these other elements, so it's best to order your " +
"manifest in the logical dependency order.",
Category.CORRECTNESS,
@@ -81,24 +81,48 @@ public class ManifestOrderDetector extends Detector implements Detector.XmlScann
"UsesMinSdkAttributes", //$NON-NLS-1$
"Checks that the minimum SDK and target SDK attributes are defined",
- "The manifest should contain a <uses-sdk> element which defines the " +
+ "The manifest should contain a `<uses-sdk>` element which defines the " +
"minimum minimum API Level required for the application to run, " +
"as well as the target version (the highest API level you have tested " +
"the version for.)",
Category.CORRECTNESS,
- 2,
+ 9,
Severity.WARNING,
ManifestOrderDetector.class,
Scope.MANIFEST_SCOPE).setMoreInfo(
"http://developer.android.com/guide/topics/manifest/uses-sdk-element.html"); //$NON-NLS-1$
- /** Missing a {@code <uses-sdk>} element */
+ /** Using a targetSdkVersion that isn't recent */
+ public static final Issue TARGET_NEWER = Issue.create(
+ "OldTargetApi", //$NON-NLS-1$
+ "Checks that the manifest specifies a targetSdkVersion that is recent",
+
+ "When your application runs on a version of Android that is more recent than your " +
+ "`targetSdkVersion` specifies that it has been tested with, various compatibility " +
+ "modes kick in. This ensures that your application continues to work, but it may " +
+ "look out of place. For example, if the `targetSdkVersion` is less than 14, your " +
+ "app may get an option button in the UI.\n" +
+ "\n" +
+ "To fix this issue, set the `targetSdkVersion` to the highest available value. Then " +
+ "test your app to make sure everything works correctly. You may want to consult " +
+ "the compatibility notes to see what changes apply to each version you are adding " +
+ "support for: " +
+ "http://developer.android.com/reference/android/os/Build.VERSION_CODES.html",
+
+ Category.CORRECTNESS,
+ 6,
+ Severity.WARNING,
+ ManifestOrderDetector.class,
+ Scope.MANIFEST_SCOPE).setMoreInfo(
+ "http://developer.android.com/reference/android/os/Build.VERSION_CODES.html"); //$NON-NLS-1$
+
+ /** Using multiple {@code <uses-sdk>} elements */
public static final Issue MULTIPLE_USES_SDK = Issue.create(
"MultipleUsesSdk", //$NON-NLS-1$
"Checks that the <uses-sdk> element appears at most once",
- "The <uses-sdk> element should appear just once; the tools will *not* merge the " +
+ "The `<uses-sdk>` element should appear just once; the tools will *not* merge the " +
"contents of all the elements so if you split up the atttributes across multiple " +
"elements, only one of them will take effect. To fix this, just merge all the " +
"attributes from the various elements into a single <uses-sdk> element.",
@@ -115,9 +139,9 @@ public class ManifestOrderDetector extends Detector implements Detector.XmlScann
"WrongManifestParent", //$NON-NLS-1$
"Checks that various manifest elements are declared in the right place",
- "The <uses-library> element should be defined as a direct child of the " +
- "<application> tag, not the <manifest> tag or an <activity> tag. Similarly, " +
- "a <uses-sdk> tag much be declared at the root level, and so on. This check " +
+ "The `<uses-library>` element should be defined as a direct child of the " +
+ "`<application>` tag, not the `<manifest>` tag or an `<activity>` tag. Similarly, " +
+ "a `<uses-sdk>` tag much be declared at the root level, and so on. This check " +
"looks for incorrect declaration locations in the manifest, and complains " +
"if an element is found in the wrong place.",
@@ -291,8 +315,9 @@ public class ManifestOrderDetector extends Detector implements Detector.XmlScann
"<uses-sdk> tag should specify a minimum API level with " +
"android:minSdkVersion=\"?\"", null);
}
- } else if (context.getProject().getMinSdk() <= 9
- && !element.hasAttributeNS(ANDROID_URI, ATTR_TARGET_SDK_VERSION)) {
+ }
+
+ if (!element.hasAttributeNS(ANDROID_URI, ATTR_TARGET_SDK_VERSION)) {
// Warn if not setting target SDK -- but only if the min SDK is somewhat
// old so there's some compatibility stuff kicking in (such as the menu
// button etc)
@@ -303,6 +328,20 @@ public class ManifestOrderDetector extends Detector implements Detector.XmlScann
"compatibility behaviors may be enabled) with " +
"android:targetSdkVersion=\"?\"", null);
}
+ } else if (context.isEnabled(TARGET_NEWER)){
+ String target = element.getAttributeNS(ANDROID_URI, ATTR_TARGET_SDK_VERSION);
+ try {
+ int api = Integer.parseInt(target);
+ if (api < context.getClient().getHighestKnownApiLevel()) {
+ context.report(TARGET_NEWER, element, context.getLocation(element),
+ "Not targeting the latest versions of Android; compatibility " +
+ "modes apply. Consider testing and updating this version. " +
+ "Consult the android.os.Build.VERSION_CODES javadoc for details.",
+ null);
+ }
+ } catch (NumberFormatException nufe) {
+ // Ignore: AAPT will enforce this.
+ }
}
}
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/MergeRootFrameLayoutDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/MergeRootFrameLayoutDetector.java
index ff2609d..5b3fe99 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/MergeRootFrameLayoutDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/MergeRootFrameLayoutDetector.java
@@ -87,10 +87,10 @@ public class MergeRootFrameLayoutDetector extends LayoutDetector implements Dete
public static final Issue ISSUE = Issue.create(
"MergeRootFrame", //$NON-NLS-1$
"Checks whether a root <FrameLayout> can be replaced with a <merge> tag",
- "If a <FrameLayout> is the root of a layout and does not provide background " +
- "or padding etc, it can often be replaced with a <merge> tag which is slightly " +
+ "If a `<FrameLayout>` is the root of a layout and does not provide background " +
+ "or padding etc, it can often be replaced with a `<merge>` tag which is slightly " +
"more efficient. Note that this depends on context, so make sure you understand " +
- "how the <merge> tag works before proceeding.",
+ "how the `<merge>` tag works before proceeding.",
Category.PERFORMANCE,
4,
Severity.WARNING,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/NestedScrollingWidgetDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/NestedScrollingWidgetDetector.java
index d6cdbd6..3f0fef3 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/NestedScrollingWidgetDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/NestedScrollingWidgetDetector.java
@@ -50,7 +50,7 @@ public class NestedScrollingWidgetDetector extends LayoutDetector {
"NestedScrolling", //$NON-NLS-1$
"Checks whether a scrolling widget has any nested scrolling widgets within",
// TODO: Better description!
- "A scrolling widget such as a ScrollView should not contain any nested " +
+ "A scrolling widget such as a `ScrollView` should not contain any nested " +
"scrolling widgets since this has various usability issues",
Category.CORRECTNESS,
7,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/NonInternationalizedSmsDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/NonInternationalizedSmsDetector.java
index 3c1b4bf..86191bf 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/NonInternationalizedSmsDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/NonInternationalizedSmsDetector.java
@@ -44,7 +44,8 @@ public class NonInternationalizedSmsDetector extends Detector implements Detecto
"Looks for code sending text messages to unlocalized phone numbers",
"SMS destination numbers must start with a country code or the application code " +
- "must ensure that the SMS is only sent when the user is in the same country as the receiver.",
+ "must ensure that the SMS is only sent when the user is in the same country as " +
+ "the receiver.",
Category.CORRECTNESS,
5,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/OnClickDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/OnClickDetector.java
index bb9c998..4283b7b 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/OnClickDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/OnClickDetector.java
@@ -60,9 +60,9 @@ public class OnClickDetector extends LayoutDetector implements ClassScanner {
"OnClick", //$NON-NLS-1$
"Ensures that onClick attribute values refer to real methods",
- "The onClick attribute value should be the name of a method in this View's context " +
+ "The `onClick` attribute value should be the name of a method in this View's context " +
"to invoke when the view is clicked. This name must correspond to a public method " +
- "that takes exactly one parameter of type View.\n" +
+ "that takes exactly one parameter of type `View`.\n" +
"\n" +
"Must be a string value, using '\\;' to escape characters such as '\\n' or " +
"'\\uxxxx' for a unicode character.",
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/PrivateResourceDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/PrivateResourceDetector.java
index 7d909ae..c1e405b 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/PrivateResourceDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/PrivateResourceDetector.java
@@ -41,7 +41,7 @@ public class PrivateResourceDetector extends ResourceXmlDetector {
"even where they are they may disappear without notice.\n" +
"\n" +
"To fix this, copy the resource into your own project. You can find the platform " +
- "resources under $ANDROID_SK/platforms/android-$VERSION/data/res/.",
+ "resources under `$ANDROID_SK/platforms/android-$VERSION/data/res/.`",
Category.CORRECTNESS,
3,
Severity.FATAL,
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 41af3b1..29db23f 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
@@ -41,11 +41,11 @@ public class ProguardDetector extends Detector {
public static final Issue WRONGKEEP = Issue.create(
"Proguard", //$NON-NLS-1$
"Looks for problems in proguard config files",
- "Using -keepclasseswithmembernames in a proguard config file is not " +
+ "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 " +
- "-keepclasseswithmembers, since the old flags also implies " +
+ "wrong format. Instead of `-keepclasseswithmembernames` use " +
+ "`-keepclasseswithmembers`, since the old flags also implies " +
"\"allow shrinking\" which means symbols only referred to from XML and " +
"not Java (such as possibly CustomViews) can get deleted.",
Category.CORRECTNESS,
@@ -61,7 +61,7 @@ public class ProguardDetector extends Detector {
"ProguardSplit", //$NON-NLS-1$
"Checks for old proguard.cfg files that contain generic Android rules",
- "Earlier versions of the Android tools bundled a single \"proguard.cfg\" file " +
+ "Earlier versions of the Android tools bundled a single `proguard.cfg` file " +
"containing a ProGuard configuration file suitable for Android shrinking and " +
"obfuscation. However, that version was copied into new projects, which " +
"means that it does not continue to get updated as we improve the default " +
@@ -76,14 +76,14 @@ public class ProguardDetector extends Detector {
"directory which means that it gets updated along with the tools.\n" +
"\n" +
"In order for this to work, the proguard.config property in the " +
- "project.properties file now refers to a path, so you can reference both " +
+ "`project.properties` file now refers to a path, so you can reference both " +
"the generic file as well as your own (and any additional files too).\n" +
"\n" +
- "To migrate your project to the new setup, create a new proguard-project.txt file " +
+ "To migrate your project to the new setup, create a new `proguard-project.txt` file " +
"in your project containing any project specific ProGuard flags as well as " +
"any customizations you have made, then update your project.properties file " +
"to contain:\n" +
- "proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt",
+ "`proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt`",
Category.CORRECTNESS,
3,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/PxUsageDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/PxUsageDetector.java
index f9e3bdd..6734592 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/PxUsageDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/PxUsageDetector.java
@@ -54,7 +54,7 @@ public class PxUsageDetector extends LayoutDetector {
"For performance reasons and to keep the code simpler, the Android system uses pixels " +
"as the standard unit for expressing dimension or coordinate values. That means that " +
"the dimensions of a view are always expressed in the code using pixels, but " +
- "always based on the current screen density. For instance, if myView.getWidth() " +
+ "always based on the current screen density. For instance, if `myView.getWidth()` " +
"returns 10, the view is 10 pixels wide on the current screen, but on a device with " +
"a higher density screen, the value returned might be 15. If you use pixel values " +
"in your application code to work with bitmaps that are not pre-scaled for the " +
@@ -72,13 +72,13 @@ public class PxUsageDetector extends LayoutDetector {
"SpUsage", //$NON-NLS-1$
"Looks for uses of \"dp\" instead of \"sp\" dimensions for text sizes",
- "When setting text sizes, you should normally use \"sp\", or \"scale-independent " +
- "pixels\". This is like the dp unit, but it is also scaled " +
+ "When setting text sizes, you should normally use `sp`, or \"scale-independent " +
+ "pixels\". This is like the `dp` unit, but it is also scaled " +
"by the user's font size preference. It is recommend you use this unit when " +
"specifying font sizes, so they will be adjusted for both the screen density " +
"and the user's preference.\n" +
"\n" +
- "There *are* cases where you might need to use \"dp\"; typically this happens when " +
+ "There *are* cases where you might need to use `dp`; typically this happens when " +
"the text is in a container with a specific dp-size. This will prevent the text " +
"from spilling outside the container. Note however that this means that the user's " +
"font size settings are not respected, so consider adjusting the layout itself " +
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/RegistrationDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/RegistrationDetector.java
index 2455365..b645253 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/RegistrationDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/RegistrationDetector.java
@@ -62,7 +62,7 @@ public class RegistrationDetector extends LayoutDetector implements ClassScanner
"Ensures that Activities, Services and Content Providers are registered in the manifest",
"Activities, services and content providers should be registered in the " +
- "AndroidManifext.xml file using <activity>, <service> and <provider> tags.\n" +
+ "`AndroidManifext.xml` file using `<activity>`, `<service>` and `<provider>` tags.\n" +
"\n" +
"If your activity is simply a parent class intended to be subclassed by other " +
"\"real\" activities, make it an abstract class.",
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ScrollViewChildDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ScrollViewChildDetector.java
index e5db5f1..e7796ea 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ScrollViewChildDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ScrollViewChildDetector.java
@@ -51,8 +51,8 @@ public class ScrollViewChildDetector extends LayoutDetector {
"ScrollViewSize", //$NON-NLS-1$
"Checks that ScrollViews use wrap_content in scrolling dimension",
// TODO add a better explanation here!
- "ScrollView children must set their layout_width or layout_height attributes " +
- "to wrap_content rather than fill_parent or match_parent in the scrolling " +
+ "ScrollView children must set their `layout_width` or `layout_height` attributes " +
+ "to `wrap_content` rather than `fill_parent` or `match_parent` in the scrolling " +
"dimension",
Category.CORRECTNESS,
7,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/SdCardDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/SdCardDetector.java
index d5e3a88..e7545a1 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/SdCardDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/SdCardDetector.java
@@ -45,8 +45,8 @@ public class SdCardDetector extends Detector implements Detector.JavaScanner {
"SdCardPath", //$NON-NLS-1$
"Looks for hardcoded references to /sdcard",
- "Your code should not reference the /sdcard path directly; instead use " +
- "Environment.getExternalStorageDirectory().getPath()",
+ "Your code should not reference the `/sdcard` path directly; instead use " +
+ "`Environment.getExternalStorageDirectory().getPath()`",
Category.CORRECTNESS,
6,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/SecurityDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/SecurityDetector.java
index c3bc919..8c79a2c 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/SecurityDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/SecurityDetector.java
@@ -77,8 +77,8 @@ public class SecurityDetector extends Detector implements Detector.XmlScanner,
public static final Issue EXPORTED_SERVICE = Issue.create(
"ExportedService", //$NON-NLS-1$
"Checks for exported services that do not require permissions",
- "Exported services (services which either set exported=true or contain " +
- "an intent-filter and do not specify exported=false) should define a " +
+ "Exported services (services which either set `exported=true` or contain " +
+ "an intent-filter and do not specify `exported=false`) should define a " +
"permission that an entity must have in order to launch the service " +
"or bind to it. Without this, any application can use this service.",
Category.SECURITY,
@@ -94,7 +94,7 @@ public class SecurityDetector extends Detector implements Detector.XmlScanner,
"Content providers are exported by default and any application on the " +
"system can potentially use them to read and write data. If the content" +
"provider provides access to sensitive data, it should be protected by " +
- "specifying export=false in the manifest or by protecting it with a " +
+ "specifying `export=false` in the manifest or by protecting it with a " +
"permission that can be granted to other applications.",
Category.SECURITY,
5,
@@ -106,8 +106,8 @@ public class SecurityDetector extends Detector implements Detector.XmlScanner,
public static final Issue EXPORTED_ACTIVITY = Issue.create(
"ExportedActivity", //$NON-NLS-1$
"Checks for exported activities that do not require permissions",
- "Exported activities (activities which either set exported=true or contain " +
- "an intent-filter and do not specify exported=false) should define a " +
+ "Exported activities (activities which either set `exported=true` or contain " +
+ "an intent-filter and do not specify `exported=false`) should define a " +
"permission that an entity must have in order to launch the activity " +
"or bind to it. Without this, any application can use this activity.",
Category.SECURITY,
@@ -120,8 +120,8 @@ public class SecurityDetector extends Detector implements Detector.XmlScanner,
public static final Issue EXPORTED_RECEIVER = Issue.create(
"ExportedReceiver", //$NON-NLS-1$
"Checks for exported receivers that do not require permissions",
- "Exported receivers (receivers which either set exported=true or contain " +
- "an intent-filter and do not specify exported=false) should define a " +
+ "Exported receivers (receivers which either set `exported=true` or contain " +
+ "an intent-filter and do not specify `exported=false`) should define a " +
"permission that an entity must have in order to launch the receiver " +
"or bind to it. Without this, any application can use this receiver.",
Category.SECURITY,
@@ -134,7 +134,7 @@ public class SecurityDetector extends Detector implements Detector.XmlScanner,
public static final Issue OPEN_PROVIDER = Issue.create(
"GrantAllUris", //$NON-NLS-1$
"Checks for <grant-uri-permission> elements where everything is shared",
- "The <grant-uri-permission> element allows specific paths to be shared. " +
+ "The `<grant-uri-permission>` element allows specific paths to be shared. " +
"This detector checks for a path URL of just '/' (everything), which is " +
"probably not what you want; you should limit access to a subset.",
Category.SECURITY,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/SetJavaScriptEnabledDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/SetJavaScriptEnabledDetector.java
index f78d8c4..361d4f9 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/SetJavaScriptEnabledDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/SetJavaScriptEnabledDetector.java
@@ -39,8 +39,8 @@ public class SetJavaScriptEnabledDetector extends Detector implements Detector.J
public static final Issue ISSUE = Issue.create("SetJavaScriptEnabled", //$NON-NLS-1$
"Looks for invocations of android.webkit.WebSettings.setJavaScriptEnabled",
- "Your code should not invoke setJavaScriptEnabled if you are not sure that" +
- "your app really requires JavaScript support.",
+ "Your code should not invoke `setJavaScriptEnabled` if you are not sure that" +
+ "your app really requires JavaScript support.",
Category.SECURITY,
6,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/SharedPrefsDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/SharedPrefsDetector.java
index 48fdbeb..685d9cf 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/SharedPrefsDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/SharedPrefsDetector.java
@@ -50,8 +50,8 @@ public class SharedPrefsDetector extends Detector implements Detector.JavaScanne
"CommitPrefEdits", //$NON-NLS-1$
"Looks for code editing a SharedPreference but forgetting to call commit() on it",
- "After calling edit() on a SharedPreference, you must call commit() or apply() on " +
- "the editor to save the results.",
+ "After calling `edit()` on a `SharedPreference`, you must call `commit()` " +
+ "or `apply()` on the editor to save the results.",
Category.CORRECTNESS,
6,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/StringFormatDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/StringFormatDetector.java
index c8671af..23cfa38 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/StringFormatDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/StringFormatDetector.java
@@ -93,18 +93,18 @@ public class StringFormatDetector extends ResourceXmlDetector implements Detecto
"Checks that format strings are valid",
"If a string contains a '%' character, then the string may be a formatting string " +
- "which will be passed to String.format from Java code to replace each '%' " +
+ "which will be passed to `String.format` from Java code to replace each '%' " +
"occurrence with specific values.\n" +
"\n" +
"This lint warning checks for two related problems:\n" +
- "(1) Formatting strings that are invalid, meaning that String.format will throw " +
+ "(1) Formatting strings that are invalid, meaning that `String.format` will throw " +
"exceptions at runtime when attempting to use the format string.\n" +
"(2) Strings containing '%' that are not formatting strings getting passed to " +
- "a String.format call. In this case the '%' will need to be escaped as '%%'.\n" +
+ "a `String.format` call. In this case the '%' will need to be escaped as '%%'.\n" +
"\n" +
"NOTE: Not all Strings which look like formatting strings are intended for " +
- "use by String.format; for example, they may contain date formats intended " +
- "for android.text.format.Time#format(). Lint cannot always figure out that " +
+ "use by `String.format`; for example, they may contain date formats intended " +
+ "for `android.text.format.Time#format()`. Lint cannot always figure out that " +
"a String is a date format, so you may get false warnings in those scenarios. " +
"See the suppress help topic for information on how to suppress errors in " +
"that case.",
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextFieldDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextFieldDetector.java
index c133ce2..518bf2e 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextFieldDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextFieldDetector.java
@@ -44,14 +44,14 @@ public class TextFieldDetector extends LayoutDetector {
public static final Issue ISSUE = Issue.create(
"TextFields", //$NON-NLS-1$
"Looks for text fields missing inputType or hint settings",
- "Providing an inputType attribute on a text field improves usability " +
+ "Providing an `inputType` attribute on a text field improves usability " +
"because depending on the data to be input, optimized keyboards can be shown " +
"to the user (such as just digits and parentheses for a phone number). Similarly," +
"a hint attribute displays a hint to the user for what is expected in the " +
"text field.\n" +
"\n" +
"If you really want to keep the text field generic, you can suppress this warning " +
- "by setting inputType=\"text\".",
+ "by setting `inputType=\"text\"`.",
Category.USABILITY,
5,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextViewDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextViewDetector.java
index e6e0371..db9155a 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextViewDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextViewDetector.java
@@ -70,14 +70,14 @@ public class TextViewDetector extends LayoutDetector {
"TextViewEdits", //$NON-NLS-1$
"Looks for TextViews being used for input",
- "Using a <TextView> to input text is generally an error, you should be " +
- "using <EditText> instead. EditText is a subclass of TextView, and some " +
- "of the editing support is provided by TextView, so it's possible to set " +
- "some input-related properties on a TextView. However, using a TextView " +
+ "Using a `<TextView>` to input text is generally an error, you should be " +
+ "using `<EditText>` instead. `EditText` is a subclass of `TextView`, and some " +
+ "of the editing support is provided by `TextView`, so it's possible to set " +
+ "some input-related properties on a `TextView`. However, using a `TextView` " +
"along with input attributes is usually a cut & paste error. To input " +
- "text you should be using <EditText>." +
+ "text you should be using `<EditText>`." +
"\n" +
- "This check also checks subclasses of TextView, such as Button and CheckBox, " +
+ "This check also checks subclasses of `TextView`, such as `Button` and `CheckBox`, " +
"since these have the same issue: they should not be used with editable " +
"attributes.",
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ToastDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ToastDetector.java
index b15d149..52ae8ed 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ToastDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ToastDetector.java
@@ -48,8 +48,8 @@ public class ToastDetector extends Detector implements Detector.JavaScanner {
"ShowToast", //$NON-NLS-1$
"Looks for code creating a Toast but forgetting to call show() on it",
- "Toast.makeText() creates a Toast but does *not* show it. You must call " +
- "show() on the resulting object to actually make the Toast appear.",
+ "`Toast.makeText()` creates a `Toast` but does *not* show it. You must call " +
+ "`show()` on the resulting object to actually make the `Toast` appear.",
Category.CORRECTNESS,
6,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TooManyViewsDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TooManyViewsDetector.java
index ed3480a..3256b91 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TooManyViewsDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TooManyViewsDetector.java
@@ -42,7 +42,7 @@ public class TooManyViewsDetector extends LayoutDetector {
"performance. Consider using compound drawables or other tricks for " +
"reducing the number of views in this layout.\n\n" +
"The maximum view count defaults to 80 but can be configured with the " +
- "environment variable ANDROID_LINT_MAX_VIEW_COUNT.",
+ "environment variable `ANDROID_LINT_MAX_VIEW_COUNT`.",
Category.PERFORMANCE,
1,
Severity.WARNING,
@@ -54,9 +54,9 @@ public class TooManyViewsDetector extends LayoutDetector {
"TooDeepLayout", //$NON-NLS-1$
"Checks whether a layout hierarchy is too deep",
"Layouts with too much nesting is bad for performance. " +
- "Consider using a flatter layout (such as RelativeLayout or GridLayout)." +
+ "Consider using a flatter layout (such as `RelativeLayout` or `GridLayout`)." +
"The default maximum depth is 10 but can be configured with the environment " +
- "variable ANDROID_LINT_MAX_DEPTH.",
+ "variable `ANDROID_LINT_MAX_DEPTH`.",
Category.PERFORMANCE,
1,
Severity.WARNING,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java
index 391033e..c796d26 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java
@@ -75,15 +75,15 @@ public class TranslationDetector extends ResourceXmlDetector {
"one language should also be translated in all other languages.\n" +
"\n" +
"If the string should *not* be translated, you can add the attribute\n" +
- "translatable=\"false\" on the <string> element, or you can define all " +
- "your non-translatable strings in a resource file called \"donottranslate.xml\". " +
- "Or, you can ignore the issue with a tools:ignore=\"MissingTranslation\" " +
+ "`translatable=\"false\"` on the `<string>` element, or you can define all " +
+ "your non-translatable strings in a resource file called `donottranslate.xml`. " +
+ "Or, you can ignore the issue with a `tools:ignore=\"MissingTranslation\"` " +
"attribute.\n" +
"\n" +
"By default this detector allows regions of a language to just provide a " +
"subset of the strings and fall back to the standard language strings. " +
"You can require all regions to provide a full translation by setting the " +
- "environment variable ANDROID_LINT_COMPLETE_REGIONS.",
+ "environment variable `ANDROID_LINT_COMPLETE_REGIONS`.",
Category.MESSAGES,
8,
Severity.FATAL,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java
index 777c4ff..e2923b0 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java
@@ -49,10 +49,13 @@ public class UseCompoundDrawableDetector extends LayoutDetector {
public static final Issue ISSUE = Issue.create(
"UseCompoundDrawables", //$NON-NLS-1$
"Checks whether the current node can be replaced by a TextView using compound drawables.",
- // TODO: OFFER MORE HELP!
- "A LinearLayout which contains an ImageView and a TextView can be more efficiently " +
- "handled as a compound drawable. If the two widgets are offset from each other with " +
- "margins, this can be replaced with a drawablePadding attribute.\n" +
+ "A `LinearLayout` which contains an `ImageView` and a `TextView` can be more " +
+ "efficiently handled as a compound drawable (a single TextView, using the " +
+ "`drawableTop`, `drawableLeft`, `drawableRight` and/or `drawableBottom` attributes " +
+ "to draw one or more images adjacent to the text).\n" +
+ "\n" +
+ "If the two widgets are offset from each other with " +
+ "margins, this can be replaced with a `drawablePadding` attribute.\n" +
"\n" +
"There's a lint quickfix to perform this conversion in the Eclipse plugin.",
Category.PERFORMANCE,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ViewConstructorDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ViewConstructorDetector.java
index 68062c5..a532ced 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ViewConstructorDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ViewConstructorDetector.java
@@ -53,13 +53,13 @@ public class ViewConstructorDetector extends Detector implements Detector.ClassS
"Some layout tools (such as the Android layout editor for Eclipse) needs to " +
"find a constructor with one of the following signatures:\n" +
- "* View(Context context)\n" +
- "* View(Context context, AttributeSet attrs)\n" +
- "* View(Context context, AttributeSet attrs, int defStyle)\n" +
+ "* `View(Context context)`\n" +
+ "* `View(Context context, AttributeSet attrs)`\n" +
+ "* `View(Context context, AttributeSet attrs, int defStyle)`\n" +
"\n" +
"If your custom view needs to perform initialization which does not apply when " +
"used in a layout editor, you can surround the given code with a check to " +
- "see if View#isInEditMode() is false, since that method will return false " +
+ "see if `View#isInEditMode()` is false, since that method will return `false` " +
"at runtime but true within a user interface editor.",
Category.USABILITY,
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/WakelockDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/WakelockDetector.java
index c828eba..066575a 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/WakelockDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/WakelockDetector.java
@@ -55,12 +55,12 @@ public class WakelockDetector extends Detector implements ClassScanner {
"Failing to release a wakelock properly can keep the Android device in " +
"a high power mode, which reduces battery life. There are several causes " +
- "of this, such as releasing the wake lock in onDestroy() instead of in " +
- "onPause(), failing to call release() in all possible code paths after " +
- "an acquire(), and so on.\n" +
+ "of this, such as releasing the wake lock in `onDestroy()` instead of in " +
+ "`onPause()`, failing to call `release()` in all possible code paths after " +
+ "an `acquire()`, and so on.\n" +
"\n" +
"NOTE: If you are using the lock just to keep the screen on, you should " +
- "strongly consider using FLAG_KEEP_SCREEN_ON instead. This window flag " +
+ "strongly consider using `FLAG_KEEP_SCREEN_ON` instead. This window flag " +
"will be correctly managed by the platform as the user moves between " +
"applications and doesn't require a special permission. See " +
"http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_KEEP_SCREEN_ON.",
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/WrongIdDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/WrongIdDetector.java
index 18db53d..8003843 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/WrongIdDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/WrongIdDetector.java
@@ -90,7 +90,7 @@ public class WrongIdDetector extends LayoutDetector {
public static final Issue UNKNOWN_ID = Issue.create(
"UnknownId", //$NON-NLS-1$
"Checks for id references in RelativeLayouts that are not defined elsewhere",
- "The \"@+id/\" syntax refers to an existing id, or creates a new one if it has " +
+ "The `@+id/` syntax refers to an existing id, or creates a new one if it has " +
"not already been defined elsewhere. However, this means that if you have a " +
"typo in your reference, or if the referred view no longer exists, you do not " +
"get a warning since the id will be created on demand. This check catches " +
@@ -107,7 +107,7 @@ public class WrongIdDetector extends LayoutDetector {
"UnknownIdInLayout", //$NON-NLS-1$
"Makes sure that @+id references refer to views in the same layout",
- "The \"@+id/\" syntax refers to an existing id, or creates a new one if it has " +
+ "The `@+id/` syntax refers to an existing id, or creates a new one if it has " +
"not already been defined elsewhere. However, this means that if you have a " +
"typo in your reference, or if the referred view no longer exists, you do not " +
"get a warning since the id will be created on demand.\n" +
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/WrongImportDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/WrongImportDetector.java
index fc6cde2..1f04eb2 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/WrongImportDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/WrongImportDetector.java
@@ -49,14 +49,13 @@ public class WrongImportDetector extends Detector implements Detector.JavaScanne
/** Is android.R being imported? */
public static final Issue ISSUE = Issue.create("SuspiciousImport", //$NON-NLS-1$
"Checks for 'import android.R' statements, which are usually accidental",
- "Importing android.R is usually not intentional; it sometimes happens when " +
- "you use an IDE and ask it to automatically add imports at a time when your " +
- "project's R class it not present.\n" +
- "\n" +
- "Once the import is there you might get a lot of \"confusing\" error messages "
- +
- "because of course the fields available on android.R are not the ones you'd " +
- "expect from just looking at your own R class.",
+ "Importing `android.R` is usually not intentional; it sometimes happens when " +
+ "you use an IDE and ask it to automatically add imports at a time when your " +
+ "project's R class it not present.\n" +
+ "\n" +
+ "Once the import is there you might get a lot of \"confusing\" error messages " +
+ "because of course the fields available on `android.R` are not the ones you'd " +
+ "expect from just looking at your own `R` class.",
Category.CORRECTNESS,
9,
Severity.WARNING,
diff --git a/lint/libs/lint_checks/tests/.classpath b/lint/libs/lint_checks/tests/.classpath
index 18970b8..752dafd 100644
--- a/lint/libs/lint_checks/tests/.classpath
+++ b/lint/libs/lint_checks/tests/.classpath
@@ -13,5 +13,6 @@
<classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/lombok-ast/lombok-ast-0.2.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/lombok-ast/src.zip"/>
<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_api"/>
<classpathentry combineaccessrules="false" kind="src" path="/common"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/lint/libs/lint_checks/tests/Android.mk b/lint/libs/lint_checks/tests/Android.mk
index b078f2b..9f591f6 100644
--- a/lint/libs/lint_checks/tests/Android.mk
+++ b/lint/libs/lint_checks/tests/Android.mk
@@ -22,7 +22,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE := lint_checks-tests
LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := common lint_api lint_checks lint junit easymock asm-tools asm-tree-tools guava-tools layoutlib_api
+LOCAL_JAVA_LIBRARIES := common sdklib lint_api lint_checks lint junit easymock asm-tools asm-tree-tools guava-tools layoutlib_api
include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/XmlReporterTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/XmlReporterTest.java
index c908319..5792e1d 100644
--- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/XmlReporterTest.java
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/XmlReporterTest.java
@@ -88,9 +88,9 @@ public class XmlReporterTest extends AbstractCheckTest {
" severity=\"Warning\"\n" +
" message=\"&lt;uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion=&quot;?&quot;\"\n" +
" category=\"Correctness\"\n" +
- " priority=\"2\"\n" +
+ " priority=\"9\"\n" +
" summary=\"Checks that the minimum SDK and target SDK attributes are defined\"\n" +
- " explanation=\"The manifest should contain a &lt;uses-sdk> element which defines the minimum minimum API Level required for the application to run, as well as the target version (the highest API level you have tested the version for.)\"\n" +
+ " explanation=\"The manifest should contain a `&lt;uses-sdk>` element which defines the minimum minimum API Level required for the application to run, as well as the target version (the highest API level you have tested the version for.)\"\n" +
" url=\"http://developer.android.com/guide/topics/manifest/uses-sdk-element.html\"\n" +
" errorLine1=\" &lt;uses-sdk android:minSdkVersion=&quot;8&quot; />\"\n" +
" errorLine2=\" ^\">\n" +
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java
index 4351a7e..25e60a8 100644
--- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java
@@ -93,7 +93,7 @@ public abstract class AbstractCheckTest extends TestCase {
protected String checkLint(List<File> files) throws Exception {
mOutput = new StringBuilder();
- TestLintClient lintClient = new TestLintClient();
+ TestLintClient lintClient = createClient();
String result = lintClient.analyze(files);
// The output typically contains a few directory/filenames.
@@ -106,6 +106,14 @@ public abstract class AbstractCheckTest extends TestCase {
return result;
}
+ protected TestLintClient createClient() {
+ return new TestLintClient();
+ }
+
+ protected TestConfiguration getConfiguration(Project project) {
+ return new TestConfiguration();
+ }
+
/**
* Run lint on the given files when constructed as a separate project
* @return The output of the lint check. On Windows, this transforms all directory
@@ -349,7 +357,7 @@ public abstract class AbstractCheckTest extends TestCase {
@Override
public Configuration getConfiguration(Project project) {
- return new TestConfiguration();
+ return AbstractCheckTest.this.getConfiguration(project);
}
@Override
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ManifestOrderDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ManifestOrderDetectorTest.java
index ad5274c..1b8c8f4 100644
--- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ManifestOrderDetectorTest.java
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ManifestOrderDetectorTest.java
@@ -17,6 +17,12 @@
package com.android.tools.lint.checks;
import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.Project;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
@SuppressWarnings("javadoc")
public class ManifestOrderDetectorTest extends AbstractCheckTest {
@@ -25,7 +31,20 @@ public class ManifestOrderDetectorTest extends AbstractCheckTest {
return new ManifestOrderDetector();
}
+ private Set<Issue> mEnabled = new HashSet<Issue>();
+
+ @Override
+ protected TestConfiguration getConfiguration(Project project) {
+ return new TestConfiguration() {
+ @Override
+ public boolean isEnabled(Issue issue) {
+ return super.isEnabled(issue) && mEnabled.contains(issue);
+ }
+ };
+ }
+
public void testOrderOk() throws Exception {
+ mEnabled = Collections.singleton(ManifestOrderDetector.ORDER);
assertEquals(
"No warnings.",
lintProject(
@@ -34,14 +53,12 @@ public class ManifestOrderDetectorTest extends AbstractCheckTest {
}
public void testBrokenOrder() throws Exception {
+ mEnabled = Collections.singleton(ManifestOrderDetector.ORDER);
assertEquals(
"AndroidManifest.xml:16: Warning: <uses-sdk> tag appears after <application> tag [ManifestOrder]\n" +
" <uses-sdk android:minSdkVersion=\"Froyo\" />\n" +
" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
- "AndroidManifest.xml:16: Warning: <uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion=\"?\" [UsesMinSdkAttributes]\n" +
- " <uses-sdk android:minSdkVersion=\"Froyo\" />\n" +
- " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
- "0 errors, 2 warnings\n" +
+ "0 errors, 1 warnings\n" +
"",
lintProject(
@@ -50,6 +67,7 @@ public class ManifestOrderDetectorTest extends AbstractCheckTest {
}
public void testMissingUsesSdk() throws Exception {
+ mEnabled = Collections.singleton(ManifestOrderDetector.USES_SDK);
assertEquals(
"AndroidManifest.xml: Warning: Manifest should specify a minimum API level with <uses-sdk android:minSdkVersion=\"?\" />; if it really supports all versions of Android set it to 1. [UsesMinSdkAttributes]\n" +
"0 errors, 1 warnings\n",
@@ -59,6 +77,7 @@ public class ManifestOrderDetectorTest extends AbstractCheckTest {
}
public void testMissingMinSdk() throws Exception {
+ mEnabled = Collections.singleton(ManifestOrderDetector.USES_SDK);
assertEquals(
"AndroidManifest.xml:7: Warning: <uses-sdk> tag should specify a minimum API level with android:minSdkVersion=\"?\" [UsesMinSdkAttributes]\n" +
" <uses-sdk android:targetSdkVersion=\"10\" />\n" +
@@ -70,21 +89,39 @@ public class ManifestOrderDetectorTest extends AbstractCheckTest {
"res/values/strings.xml"));
}
+ public void testMissingTargetSdk() throws Exception {
+ mEnabled = Collections.singleton(ManifestOrderDetector.USES_SDK);
+ assertEquals(
+ "AndroidManifest.xml:7: Warning: <uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion=\"?\" [UsesMinSdkAttributes]\n" +
+ " <uses-sdk android:minSdkVersion=\"10\" />\n" +
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
+ "0 errors, 1 warnings\n",
+ lintProject(
+ "missingtarget.xml=>AndroidManifest.xml",
+ "res/values/strings.xml"));
+ }
+
+ public void testOldTargetSdk() throws Exception {
+ mEnabled = Collections.singleton(ManifestOrderDetector.TARGET_NEWER);
+ assertEquals(
+ "AndroidManifest.xml:7: Warning: Not targeting the latest versions of Android; compatibility modes apply. Consider testing and updating this version. Consult the android.os.Build.VERSION_CODES javadoc for details. [OldTargetApi]\n" +
+ " <uses-sdk android:minSdkVersion=\"10\" android:targetSdkVersion=\"14\" />\n" +
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
+ "0 errors, 1 warnings\n",
+ lintProject(
+ "oldtarget.xml=>AndroidManifest.xml",
+ "res/values/strings.xml"));
+ }
+
public void testMultipleSdk() throws Exception {
+ mEnabled = Collections.singleton(ManifestOrderDetector.MULTIPLE_USES_SDK);
assertEquals(
"AndroidManifest.xml:8: Error: There should only be a single <uses-sdk> element in the manifest: merge these together [MultipleUsesSdk]\n" +
" <uses-sdk android:targetSdkVersion=\"14\" />\n" +
" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
" AndroidManifest.xml:7: Also appears here\n" +
" AndroidManifest.xml:9: Also appears here\n" +
- "AndroidManifest.xml:7: Warning: <uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion=\"?\" [UsesMinSdkAttributes]\n" +
- " <uses-sdk android:minSdkVersion=\"5\" />\n" +
- " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
- "AndroidManifest.xml:9: Warning: <uses-sdk> tag should specify a minimum API level with android:minSdkVersion=\"?\" [UsesMinSdkAttributes]\n" +
- " <uses-sdk android:maxSdkVersion=\"15\" />\n" +
- " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
- "1 errors, 2 warnings\n" +
- "",
+ "1 errors, 0 warnings\n",
lintProject(
"multiplesdk.xml=>AndroidManifest.xml",
@@ -92,11 +129,8 @@ public class ManifestOrderDetectorTest extends AbstractCheckTest {
}
public void testWrongLocation() throws Exception {
+ mEnabled = Collections.singleton(ManifestOrderDetector.WRONG_PARENT);
assertEquals(
- "AndroidManifest.xml:14: Error: There should only be a single <uses-sdk> element in the manifest: merge these together [MultipleUsesSdk]\n" +
- " <uses-sdk />\n" +
- " ~~~~~~~~~~~~\n" +
- " AndroidManifest.xml:8: Also appears here\n" +
"AndroidManifest.xml:8: Error: The <uses-sdk> element must be a direct child of the <manifest> root element [WrongManifestParent]\n" +
" <uses-sdk android:minSdkVersion=\"Froyo\" />\n" +
" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
@@ -136,19 +170,14 @@ public class ManifestOrderDetectorTest extends AbstractCheckTest {
"AndroidManifest.xml:25: Error: The <activity> element must be a direct child of the <application> element [WrongManifestParent]\n" +
" <activity android:name=\".HelloWorld\"\n" +
" ^\n" +
- "AndroidManifest.xml:8: Warning: <uses-sdk> tag appears after <application> tag [ManifestOrder]\n" +
- " <uses-sdk android:minSdkVersion=\"Froyo\" />\n" +
- " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
- "AndroidManifest.xml:8: Warning: <uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion=\"?\" [UsesMinSdkAttributes]\n" +
- " <uses-sdk android:minSdkVersion=\"Froyo\" />\n" +
- " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
- "14 errors, 2 warnings\n" +
+ "13 errors, 0 warnings\n" +
"",
lintProject("broken-manifest2.xml=>AndroidManifest.xml"));
}
public void testDuplicateActivity() throws Exception {
+ mEnabled = Collections.singleton(ManifestOrderDetector.DUPLICATE_ACTIVITY);
assertEquals(
"AndroidManifest.xml:16: Error: Duplicate registration for activity com.example.helloworld.HelloWorld [DuplicateActivity]\n" +
" <activity android:name=\"com.example.helloworld.HelloWorld\"\n" +
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/missingtarget.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/missingtarget.xml
new file mode 100644
index 0000000..1f4fba0
--- /dev/null
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/missingtarget.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.bytecode"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="10" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <activity
+ android:name=".BytecodeTestsActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/oldtarget.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/oldtarget.xml
new file mode 100644
index 0000000..d72d7fc
--- /dev/null
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/oldtarget.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.bytecode"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <activity
+ android:name=".BytecodeTestsActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/client/api/LintClientTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/client/api/LintClientTest.java
new file mode 100644
index 0000000..2a3a43a
--- /dev/null
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/client/api/LintClientTest.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.lint.client.api;
+
+import com.android.tools.lint.Main;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings("javadoc")
+public class LintClientTest extends TestCase {
+ public void test() throws Exception {
+ Main client = new Main();
+ int max = client.getHighestKnownApiLevel();
+ assertTrue(max >= 16);
+ }
+}
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/IssueTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/IssueTest.java
new file mode 100644
index 0000000..740e921
--- /dev/null
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/IssueTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.lint.detector.api;
+
+import static com.android.tools.lint.detector.api.Issue.convertMarkup;
+import static com.android.tools.lint.detector.api.LintConstants.AUTO_URI;
+import junit.framework.TestCase;
+
+@SuppressWarnings("javadoc")
+public class IssueTest extends TestCase {
+ public void testConvertMarkup() throws Exception {
+ assertEquals("", convertMarkup("", true));
+
+ // Normal escapes
+ assertEquals("foo bar", convertMarkup("foo bar", true));
+ assertEquals("foo<br/>\nbar", convertMarkup("foo\nbar", true));
+ assertEquals("foo<br/>\nbar", convertMarkup("foo\nbar", true));
+ assertEquals("&lt;&amp;>'\"", convertMarkup("<&>'\"", true));
+
+ // HTML Formatting
+ assertEquals("<code>@TargetApi(11)</code>, ", convertMarkup("`@TargetApi(11)`, ",
+ true));
+ assertEquals("with <code>getArguments()</code>.",
+ convertMarkup("with `getArguments()`.",
+ true));
+ assertEquals("(<code>dip</code>)", convertMarkup("(`dip`)", true));
+ assertEquals(" <code>0dp</code> ", convertMarkup(" `0dp` ", true));
+ assertEquals(
+ "resources under <code>$ANDROID_SK/platforms/android-$VERSION/data/res/.</code>",
+ convertMarkup(
+ "resources under `$ANDROID_SK/platforms/android-$VERSION/data/res/.`",
+ true));
+ assertEquals("wrong format. Instead of <code>-keepclasseswithmembernames</code> use ",
+ convertMarkup("wrong format. Instead of `-keepclasseswithmembernames` use ",
+ true));
+ assertEquals("<code>exported=false</code>)", convertMarkup("`exported=false`)",
+ true));
+ assertEquals("by setting <code>inputType=\"text\"</code>.",
+ convertMarkup("by setting `inputType=\"text\"`.", true));
+ assertEquals("* <code>View(Context context)</code><br/>\n",
+ convertMarkup("* `View(Context context)`\n", true));
+ assertEquals("The <code>@+id/</code> syntax", convertMarkup("The `@+id/` syntax",
+ true));
+ assertEquals("", convertMarkup("", true));
+ assertEquals("", convertMarkup("", true));
+ assertEquals("This is <b>bold</b>", convertMarkup("This is *bold*", true));
+ assertEquals("Visit <a href=\"http://google.com\">http://google.com</a>.",
+ convertMarkup("Visit http://google.com.", true));
+ assertEquals("This is <code>monospace</code>!", convertMarkup("This is `monospace`!",
+ true));
+ assertEquals(
+ "See <a href=\"http://developer.android.com/reference/android/view/" +
+ "WindowManager.LayoutParams.html#FLAG_KEEP_SCREEN_ON\">http://developer." +
+ "android.com/reference/android/view/WindowManager.LayoutParams.html#" +
+ "FLAG_KEEP_SCREEN_ON</a>.",
+ convertMarkup(
+ "See http://developer.android.com/reference/android/view/WindowManager.Layout" +
+ "Params.html#FLAG_KEEP_SCREEN_ON.", true));
+
+ // Text formatting
+ assertEquals("@TargetApi(11), ", convertMarkup("`@TargetApi(11)`, ", false));
+ assertEquals("with getArguments().", convertMarkup("with `getArguments()`.", false));
+ assertEquals("bold", convertMarkup("*bold*", false));
+ assertEquals("Visit http://google.com.", convertMarkup("Visit http://google.com.",
+ false));
+
+ // Corners (match at the beginning and end)
+ assertEquals("<b>bold</b>", convertMarkup("*bold*", true));
+ assertEquals("<code>monospace</code>!", convertMarkup("`monospace`!", true));
+
+ // Not formatting
+ assertEquals("a*b", convertMarkup("a*b", true));
+ assertEquals("a* b*", convertMarkup("a* b*", true));
+ assertEquals("*a *b", convertMarkup("*a *b", true));
+ assertEquals("Prefix is http:// ", convertMarkup("Prefix is http:// ", true));
+ assertEquals("", convertMarkup("", true));
+ assertEquals("", convertMarkup("", true));
+ assertEquals("", convertMarkup("", true));
+ assertEquals("", convertMarkup("", true));
+ assertEquals("This is * not * bold", convertMarkup("This is * not * bold", true));
+ assertEquals("* List item 1<br/>\n* List Item 2",
+ convertMarkup("* List item 1\n* List Item 2", true));
+ assertEquals("myhttp://foo.bar", convertMarkup("myhttp://foo.bar", true));
+ }
+
+ public void testConvertMarkup2() throws Exception {
+ // http at the end:
+ // Explanation from ManifestOrderDetector#TARGET_NEWER
+ String explanation =
+ "When your application runs on a version of Android that is more recent than your " +
+ "targetSdkVersion specifies that it has been tested with, various compatibility " +
+ "modes kick in. This ensures that your application continues to work, but it may " +
+ "look out of place. For example, if the targetSdkVersion is less than 14, your " +
+ "app may get an option button in the UI.\n" +
+ "\n" +
+ "To fix this issue, set the targetSdkVersion to the highest available value. Then " +
+ "test your app to make sure everything works correctly. You may want to consult " +
+ "the compatibility notes to see what changes apply to each version you are adding " +
+ "support for: " +
+ "http://developer.android.com/reference/android/os/Build.VERSION_CODES.html";
+
+ assertEquals(
+ "When your application runs on a version of Android that is more recent than your " +
+ "targetSdkVersion specifies that it has been tested with, various compatibility " +
+ "modes kick in. This ensures that your application continues to work, but it may " +
+ "look out of place. For example, if the targetSdkVersion is less than 14, your " +
+ "app may get an option button in the UI.<br/>\n" +
+ "<br/>\n" +
+ "To fix this issue, set the targetSdkVersion to the highest available value. Then " +
+ "test your app to make sure everything works correctly. You may want to consult " +
+ "the compatibility notes to see what changes apply to each version you are adding " +
+ "support for: " +
+ "<a href=\"http://developer.android.com/reference/android/os/Build.VERSION_CODES." +
+ "html\">http://developer.android.com/reference/android/os/Build.VERSION_CODES.html" +
+ "</a>",
+ convertMarkup(explanation, true));
+ }
+
+ public void testConvertMarkup3() throws Exception {
+ // embedded http markup test
+ // Explanation from NamespaceDetector#CUSTOMVIEW
+ String explanation =
+ "When using a custom view with custom attributes in a library project, the layout " +
+ "must use the special namespace " + AUTO_URI + " instead of a URI which includes " +
+ "the library project's own package. This will be used to automatically adjust the " +
+ "namespace of the attributes when the library resources are merged into the " +
+ "application project.";
+ assertEquals(
+ "When using a custom view with custom attributes in a library project, the layout " +
+ "must use the special namespace " +
+ "<a href=\"http://schemas.android.com/apk/res-auto\">" +
+ "http://schemas.android.com/apk/res-auto</a> " +
+ "instead of a URI which includes the library project's own package. " +
+ "This will be used to automatically adjust the namespace of the attributes when " +
+ "the library resources are merged into the application project.",
+ convertMarkup(explanation, true));
+ }
+
+ public void testConvertMarkup4() throws Exception {
+ // monospace test
+ String explanation =
+ "The manifest should contain a `<uses-sdk>` element which defines the " +
+ "minimum minimum API Level required for the application to run, " +
+ "as well as the target version (the highest API level you have tested " +
+ "the version for.)";
+
+ assertEquals(
+ "The manifest should contain a <code>&lt;uses-sdk></code> element which defines the " +
+ "minimum minimum API Level required for the application to run, " +
+ "as well as the target version (the highest API level you have tested " +
+ "the version for.)",
+ convertMarkup(explanation, true));
+ }
+
+ public void testConvertMarkup5() throws Exception {
+ // monospace and bold test
+ // From ManifestOrderDetector#MULTIPLE_USES_SDK
+ String explanation =
+ "The `<uses-sdk>` element should appear just once; the tools will *not* merge the " +
+ "contents of all the elements so if you split up the atttributes across multiple " +
+ "elements, only one of them will take effect. To fix this, just merge all the " +
+ "attributes from the various elements into a single <uses-sdk> element.";
+
+ assertEquals(
+ "The <code>&lt;uses-sdk></code> element should appear just once; the tools " +
+ "will <b>not</b> merge the " +
+ "contents of all the elements so if you split up the atttributes across multiple " +
+ "elements, only one of them will take effect. To fix this, just merge all the " +
+ "attributes from the various elements into a single &lt;uses-sdk> element.",
+ convertMarkup(explanation, true));
+ }
+
+ public void testConvertMarkup6() throws Exception {
+ // Embedded code next to attributes
+ // From AlwaysShowActionDetector#ISSUE
+ String explanation =
+ "Using `showAsAction=\"always\"` in menu XML, or `MenuItem.SHOW_AS_ACTION_ALWAYS` in "+
+ "Java code is usually a deviation from the user interface style guide." +
+ "Use `ifRoom` or the corresponding `MenuItem.SHOW_AS_ACTION_IF_ROOM` instead.\n" +
+ "\n" +
+ "If `always` is used sparingly there are usually no problems and behavior is " +
+ "roughly equivalent to `ifRoom` but with preference over other `ifRoom` " +
+ "items. Using it more than twice in the same menu is a bad idea.\n" +
+ "\n" +
+ "This check looks for menu XML files that contain more than two `always` " +
+ "actions, or some `always` actions and no `ifRoom` actions. In Java code, " +
+ "it looks for projects that contain references to `MenuItem.SHOW_AS_ACTION_ALWAYS` " +
+ "and no references to `MenuItem.SHOW_AS_ACTION_IF_ROOM`.";
+
+ assertEquals(
+ "Using <code>showAsAction=\"always\"</code> in menu XML, or " +
+ "<code>MenuItem.SHOW_AS_ACTION_ALWAYS</code> in Java code is usually a deviation " +
+ "from the user interface style guide.Use <code>ifRoom</code> or the " +
+ "corresponding <code>MenuItem.SHOW_AS_ACTION_IF_ROOM</code> instead.<br/>\n" +
+ "<br/>\n" +
+ "If <code>always</code> is used sparingly there are usually no problems and " +
+ "behavior is roughly equivalent to <code>ifRoom</code> but with preference over " +
+ "other <code>ifRoom</code> items. Using it more than twice in the same menu " +
+ "is a bad idea.<br/>\n" +
+ "<br/>\n" +
+ "This check looks for menu XML files that contain more than two <code>always</code> " +
+ "actions, or some <code>always</code> actions and no <code>ifRoom</code> actions. " +
+ "In Java code, it looks for projects that contain references to " +
+ "<code>MenuItem.SHOW_AS_ACTION_ALWAYS</code> and no references to " +
+ "<code>MenuItem.SHOW_AS_ACTION_IF_ROOM</code>.",
+ convertMarkup(explanation, true));
+ }
+}
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/LintUtilsTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/LintUtilsTest.java
index 8379618..0ce3815 100644
--- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/LintUtilsTest.java
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/detector/api/LintUtilsTest.java
@@ -16,8 +16,8 @@
package com.android.tools.lint.detector.api;
-import static com.android.tools.lint.detector.api.LintUtils.splitPath;
import static com.android.tools.lint.detector.api.LintUtils.getLocaleAndRegion;
+import static com.android.tools.lint.detector.api.LintUtils.splitPath;
import com.android.tools.lint.Main;
import com.google.common.collect.Iterables;
diff --git a/templates/activities/BlankActivity/root/AndroidManifest.xml.ftl b/templates/activities/BlankActivity/root/AndroidManifest.xml.ftl
index 1c6fbd1..b8ae72e 100644
--- a/templates/activities/BlankActivity/root/AndroidManifest.xml.ftl
+++ b/templates/activities/BlankActivity/root/AndroidManifest.xml.ftl
@@ -2,13 +2,17 @@
<application>
<activity android:name=".${activityClass}"
+ <#if isNewProject>
+ android:label="@string/app_name"
+ <#else>
android:label="@string/title_${activityToLayout(activityClass)}"
+ </#if>
<#if buildApi gte 16 && parentActivityClass != "">android:parentActivityName="${parentActivityClass}"</#if>>
<#if parentActivityClass != "">
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="${parentActivityClass}" />
</#if>
- <#if isLauncher?string == "true">
+ <#if isLauncher>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
diff --git a/templates/activities/BlankActivity/root/res/values/strings.xml.ftl b/templates/activities/BlankActivity/root/res/values/strings.xml.ftl
index 4018308..6c636d6 100644
--- a/templates/activities/BlankActivity/root/res/values/strings.xml.ftl
+++ b/templates/activities/BlankActivity/root/res/values/strings.xml.ftl
@@ -1,5 +1,7 @@
<resources>
+ <#if !isNewProject>
<string name="title_${activityToLayout(activityClass)}">${activityTitle}</string>
+ </#if>
<string name="menu_settings">Settings</string>
diff --git a/templates/activities/BlankActivity/template.xml b/templates/activities/BlankActivity/template.xml
index 77aae56..31e8bb3 100644
--- a/templates/activities/BlankActivity/template.xml
+++ b/templates/activities/BlankActivity/template.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<template
- format="1"
- revision="1"
+ format="3"
+ revision="2"
name="New Blank Activity"
description="Creates a new blank activity, with optional inner navigation.">
<dependency name="android-support-v4" revision="8" />
diff --git a/templates/activities/FullscreenActivity/root/AndroidManifest.xml.ftl b/templates/activities/FullscreenActivity/root/AndroidManifest.xml.ftl
index 3142546..b909732 100644
--- a/templates/activities/FullscreenActivity/root/AndroidManifest.xml.ftl
+++ b/templates/activities/FullscreenActivity/root/AndroidManifest.xml.ftl
@@ -2,7 +2,11 @@
<application>
<activity android:name=".${activityClass}"
+ <#if isNewProject>
+ android:label="@string/app_name"
+ <#else>
android:label="@string/title_${simpleName}"
+ </#if>
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@style/FullscreenTheme"
<#if buildApi gte 16 && parentActivityClass != "">android:parentActivityName="${parentActivityClass}"</#if>>
@@ -10,7 +14,7 @@
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="${parentActivityClass}" />
</#if>
- <#if isLauncher?string == "true">
+ <#if isLauncher>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
diff --git a/templates/activities/FullscreenActivity/root/res/values/strings.xml.ftl b/templates/activities/FullscreenActivity/root/res/values/strings.xml.ftl
index 78275fa..53ff7df 100644
--- a/templates/activities/FullscreenActivity/root/res/values/strings.xml.ftl
+++ b/templates/activities/FullscreenActivity/root/res/values/strings.xml.ftl
@@ -1,6 +1,8 @@
<resources>
+ <#if !isNewProject>
<string name="title_${simpleName}">${activityTitle}</string>
+ </#if>
<string name="dummy_button1">Button 1</string>
<string name="dummy_button2">Button 2</string>
<string name="dummy_content">DUMMY\nCONTENT</string>
diff --git a/templates/activities/FullscreenActivity/template.xml b/templates/activities/FullscreenActivity/template.xml
index 90367dd..bb2dbd5 100644
--- a/templates/activities/FullscreenActivity/template.xml
+++ b/templates/activities/FullscreenActivity/template.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<template
- format="1"
- revision="1"
+ format="3"
+ revision="2"
name="New Fullscreen Activity"
description="Creates a new activity that shows and hides the system UI (status bar, navigation/system bar), and action bar, upon user interaction."
minApi="3"
diff --git a/templates/activities/LoginActivity/root/AndroidManifest.xml.ftl b/templates/activities/LoginActivity/root/AndroidManifest.xml.ftl
index 3825bb4..c5f02d2 100644
--- a/templates/activities/LoginActivity/root/AndroidManifest.xml.ftl
+++ b/templates/activities/LoginActivity/root/AndroidManifest.xml.ftl
@@ -2,7 +2,11 @@
<application>
<activity android:name=".${activityClass}"
+ <#if isNewProject>
+ android:label="@string/app_name"
+ <#else>
android:label="@string/title_${simpleName}"
+ </#if>
android:windowSoftInputMode="adjustResize|stateVisible"
<#if buildApi gte 16 && parentActivityClass != "">android:parentActivityName="${parentActivityClass}"</#if>>
<#if parentActivityClass != "">
diff --git a/templates/activities/LoginActivity/root/res/values/strings.xml.ftl b/templates/activities/LoginActivity/root/res/values/strings.xml.ftl
index 1410671..c2ad046 100644
--- a/templates/activities/LoginActivity/root/res/values/strings.xml.ftl
+++ b/templates/activities/LoginActivity/root/res/values/strings.xml.ftl
@@ -1,5 +1,7 @@
<resources>
+ <#if !isNewProject>
<string name="title_${simpleName}">${activityTitle}</string>
+ </#if>
<!-- Strings related to login -->
<string name="prompt_email">Email</string>
diff --git a/templates/activities/LoginActivity/template.xml b/templates/activities/LoginActivity/template.xml
index 7df8895..600aa4e 100644
--- a/templates/activities/LoginActivity/template.xml
+++ b/templates/activities/LoginActivity/template.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<template
- format="1"
- revision="1"
+ format="3"
+ revision="2"
name="New Login Activity"
description="Creates a new login activity, allowing users to enter an email address and password to login or register for your service."
minApi="3"
diff --git a/templates/activities/MasterDetailFlow/root/AndroidManifest.xml.ftl b/templates/activities/MasterDetailFlow/root/AndroidManifest.xml.ftl
index 395b227..4707bd6 100644
--- a/templates/activities/MasterDetailFlow/root/AndroidManifest.xml.ftl
+++ b/templates/activities/MasterDetailFlow/root/AndroidManifest.xml.ftl
@@ -2,13 +2,17 @@
<application>
<activity android:name=".${CollectionName}Activity"
+ <#if isNewProject>
+ android:label="@string/app_name"
+ <#else>
android:label="@string/title_${collection_name}"
+ </#if>
<#if buildApi gte 16 && parentActivityClass != "">android:parentActivityName="${parentActivityClass}"</#if>>
<#if parentActivityClass != "">
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="${parentActivityClass}" />
</#if>
- <#if isLauncher?string == "true">
+ <#if isLauncher>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
diff --git a/templates/activities/MasterDetailFlow/root/res/values/strings.xml.ftl b/templates/activities/MasterDetailFlow/root/res/values/strings.xml.ftl
index 4f8aeca..8c555ae 100644
--- a/templates/activities/MasterDetailFlow/root/res/values/strings.xml.ftl
+++ b/templates/activities/MasterDetailFlow/root/res/values/strings.xml.ftl
@@ -1,4 +1,6 @@
<resources>
+ <#if !isNewProject>
<string name="title_${collection_name}">${objectKindPlural}</string>
+ </#if>
<string name="title_${detail_name}">${objectKind} Detail</string>
</resources>
diff --git a/templates/activities/MasterDetailFlow/template.xml b/templates/activities/MasterDetailFlow/template.xml
index 19b7651..5c97b2b 100644
--- a/templates/activities/MasterDetailFlow/template.xml
+++ b/templates/activities/MasterDetailFlow/template.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<template
- format="1"
- revision="1"
+ format="3"
+ revision="2"
name="New Master/Detail Flow"
minApi="11"
description="Creates a new master/detail flow, which is two columns on tablets, and one column on smaller screens. This creates a master fragment, detail fragment, and two activities.">
diff --git a/templates/activities/SettingsActivity/root/AndroidManifest.xml.ftl b/templates/activities/SettingsActivity/root/AndroidManifest.xml.ftl
index 7f2efb8..9f78fcf 100644
--- a/templates/activities/SettingsActivity/root/AndroidManifest.xml.ftl
+++ b/templates/activities/SettingsActivity/root/AndroidManifest.xml.ftl
@@ -2,7 +2,11 @@
<application>
<activity android:name=".${activityClass}"
+ <#if isNewProject>
+ android:label="@string/app_name"
+ <#else>
android:label="@string/title_${simpleName}"
+ </#if>
<#if buildApi gte 16 && parentActivityClass != "">android:parentActivityName="${parentActivityClass}"</#if>>
<#if parentActivityClass != "">
<meta-data android:name="android.support.PARENT_ACTIVITY"
diff --git a/templates/activities/SettingsActivity/root/res/values/strings.xml.ftl b/templates/activities/SettingsActivity/root/res/values/strings.xml.ftl
index 164c24f..bf881a3 100644
--- a/templates/activities/SettingsActivity/root/res/values/strings.xml.ftl
+++ b/templates/activities/SettingsActivity/root/res/values/strings.xml.ftl
@@ -1,5 +1,7 @@
<resources>
+ <#if !isNewProject>
<string name="title_${simpleName}">${activityTitle}</string>
+ </#if>
<!-- Strings related to Settings -->
diff --git a/templates/activities/SettingsActivity/template.xml b/templates/activities/SettingsActivity/template.xml
index f6c8dfe..a5d084f 100644
--- a/templates/activities/SettingsActivity/template.xml
+++ b/templates/activities/SettingsActivity/template.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<template
- format="1"
- revision="1"
+ format="3"
+ revision="2"
name="New Settings Activity"
description="Creates a new application settings activity."
minApi="4"