diff options
author | Tor Norbye <tnorbye@google.com> | 2012-12-03 11:11:57 -0800 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2012-12-03 11:11:58 -0800 |
commit | 37556ca0ffd86ee9e7080289446fde005ce0e23a (patch) | |
tree | a8e48e8733e739f223864a14f60ab23754a4b95d | |
parent | c3b3bb82b50c5fcc81aeca72ea9043aa756cc69c (diff) | |
parent | defb28521b99e2b42d6e60e2eda1259803514196 (diff) | |
download | sdk-37556ca0ffd86ee9e7080289446fde005ce0e23a.zip sdk-37556ca0ffd86ee9e7080289446fde005ce0e23a.tar.gz sdk-37556ca0ffd86ee9e7080289446fde005ce0e23a.tar.bz2 |
Merge "Add tools:targetApi to control local minSdk (like @TargetApi)"
10 files changed, 216 insertions, 64 deletions
diff --git a/common/src/com/android/SdkConstants.java b/common/src/com/android/SdkConstants.java index 0708647..48cecc1 100644 --- a/common/src/com/android/SdkConstants.java +++ b/common/src/com/android/SdkConstants.java @@ -979,6 +979,7 @@ public final class SdkConstants { public static final String SUPPRESS_ALL = "all"; //$NON-NLS-1$ public static final String SUPPRESS_LINT = "SuppressLint"; //$NON-NLS-1$ public static final String TARGET_API = "TargetApi"; //$NON-NLS-1$ + public static final String ATTR_TARGET_API = "targetApi"; //$NON-NLS-1$ public static final String FQCN_SUPPRESS_LINT = "android.annotation." + SUPPRESS_LINT; //$NON-NLS-1$ public static final String FQCN_TARGET_API = "android.annotation." + TARGET_API; //$NON-NLS-1$ 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 6e051df..c98e94f 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 @@ -815,42 +815,6 @@ public class AdtUtils { } /** - * Returns the applicable build code (for - * {@code android.os.Build.VERSION_CODES}) for the corresponding API level, - * or null if it's unknown. - * - * @param api the API level to look up a version code for - * @return the corresponding build code field name, or null - */ - @Nullable - public static String getBuildCodes(int api) { - // See http://developer.android.com/reference/android/os/Build.VERSION_CODES.html - switch (api) { - case 1: return "BASE"; //$NON-NLS-1$ - case 2: return "BASE_1_1"; //$NON-NLS-1$ - case 3: return "CUPCAKE"; //$NON-NLS-1$ - case 4: return "DONUT"; //$NON-NLS-1$ - case 5: return "ECLAIR"; //$NON-NLS-1$ - case 6: return "ECLAIR_0_1"; //$NON-NLS-1$ - case 7: return "ECLAIR_MR1"; //$NON-NLS-1$ - case 8: return "FROYO"; //$NON-NLS-1$ - case 9: return "GINGERBREAD"; //$NON-NLS-1$ - case 10: return "GINGERBREAD_MR1"; //$NON-NLS-1$ - case 11: return "HONEYCOMB"; //$NON-NLS-1$ - case 12: return "HONEYCOMB_MR1"; //$NON-NLS-1$ - case 13: return "HONEYCOMB_MR2"; //$NON-NLS-1$ - 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$ - case 17: return "JELLY_BEAN_MR1"; //$NON-NLS-1$ - // If you add more versions here, also update #getAndroidName and - // SdkConstants#HIGHEST_KNOWN_API - } - - return null; - } - - /** * Returns a string label for the given target, of the form * "API 16: Android 4.1 (Jelly Bean)". * @@ -994,7 +958,7 @@ public class AdtUtils { case 15: return "API 15: Android 4.0.3 (IceCreamSandwich)"; case 16: return "API 16: Android 4.1 (Jelly Bean)"; case 17: return "API 17: Android 4.2 (Jelly Bean)"; - // If you add more versions here, also update #getBuildCodes and + // If you add more versions here, also update LintUtils#getBuildCodes and // SdkConstants#HIGHEST_KNOWN_API default: { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/AddSuppressAnnotation.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/AddSuppressAnnotation.java index 80dac65..59dbe82 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/AddSuppressAnnotation.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/AddSuppressAnnotation.java @@ -31,6 +31,7 @@ import com.android.ide.eclipse.adt.internal.editors.IconFactory; import com.android.tools.lint.checks.AnnotationDetector; import com.android.tools.lint.checks.ApiDetector; import com.android.tools.lint.detector.api.Issue; +import com.android.tools.lint.detector.api.LintUtils; import com.android.tools.lint.detector.api.Scope; import org.eclipse.core.resources.IMarker; @@ -407,7 +408,7 @@ class AddSuppressAnnotation implements IMarkerResolution2 { // @TargetApi is only valid on methods and classes, not fields etc && (body instanceof MethodDeclaration || body instanceof TypeDeclaration)) { - String apiString = AdtUtils.getBuildCodes(api); + String apiString = LintUtils.getBuildCode(api); if (apiString == null) { apiString = Integer.toString(api); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/AddSuppressAttribute.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/AddSuppressAttribute.java index 23943d5..fdb0383 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/AddSuppressAttribute.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/AddSuppressAttribute.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.lint; import static com.android.SdkConstants.ATTR_IGNORE; +import static com.android.SdkConstants.ATTR_TARGET_API; import static com.android.SdkConstants.DOT_XML; import com.android.annotations.NonNull; @@ -26,6 +27,9 @@ import com.android.ide.eclipse.adt.AdtUtils; import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; import com.android.ide.eclipse.adt.internal.editors.IconFactory; import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities; +import com.android.tools.lint.checks.ApiDetector; +import com.android.tools.lint.detector.api.LintUtils; +import com.google.common.collect.Lists; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; @@ -38,6 +42,12 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * Fix for adding {@code tools:ignore="id"} attributes in XML files. */ @@ -47,14 +57,26 @@ class AddSuppressAttribute implements ICompletionProposal { private final IMarker mMarker; private final Element mElement; private final String mDescription; + /** + * Should it create a {@code tools:targetApi} attribute instead of a + * {@code tools:ignore} attribute? If so pass a non null API level + */ + private final String mTargetApi; + - private AddSuppressAttribute(AndroidXmlEditor editor, String id, IMarker marker, - Element element, String description) { + private AddSuppressAttribute( + @NonNull AndroidXmlEditor editor, + @NonNull String id, + @NonNull IMarker marker, + @NonNull Element element, + @NonNull String description, + @Nullable String targetApi) { mEditor = editor; mId = id; mMarker = marker; mElement = element; mDescription = description; + mTargetApi = targetApi; } @Override @@ -84,7 +106,16 @@ class AddSuppressAttribute implements ICompletionProposal { @Override public void apply(IDocument document) { - AdtUtils.setToolsAttribute(mEditor, mElement, "Suppress Lint Warning", ATTR_IGNORE, mId, + String attribute; + String value; + if (mTargetApi != null) { + attribute = ATTR_TARGET_API; + value = mTargetApi; + } else { + attribute = ATTR_IGNORE; + value = mId; + } + AdtUtils.setToolsAttribute(mEditor, mElement, mDescription, attribute, value, true /*reveal*/, true /*append*/); try { @@ -92,7 +123,7 @@ class AddSuppressAttribute implements ICompletionProposal { // (so the user doesn't have to re-run lint just to see it disappear) mMarker.delete(); } catch (CoreException e) { - AdtPlugin.log(e, "Could not add suppress annotation"); + AdtPlugin.log(e, "Could not remove marker"); } } @@ -103,17 +134,17 @@ class AddSuppressAttribute implements ICompletionProposal { * @param editor the associated editor containing the marker * @param marker the marker to create fixes for * @param id the issue id - * @return a fix for this marker, or null if unable + * @return a list of fixes for this marker, possibly empty */ - @Nullable - public static AddSuppressAttribute createFix( + @NonNull + public static List<AddSuppressAttribute> createFixes( @NonNull AndroidXmlEditor editor, @NonNull IMarker marker, @NonNull String id) { // This only applies to XML files: String fileName = marker.getResource().getName(); if (!fileName.endsWith(DOT_XML)) { - return null; + return Collections.emptyList(); } int offset = marker.getAttribute(IMarker.CHAR_START, -1); @@ -127,7 +158,7 @@ class AddSuppressAttribute implements ICompletionProposal { node = DomUtilities.getNode(editor.getStructuredDocument(), offset); } if (node == null) { - return null; + return Collections.emptyList(); } Document document = node.getOwnerDocument(); while (node != null && node.getNodeType() != Node.ELEMENT_NODE) { @@ -136,13 +167,40 @@ class AddSuppressAttribute implements ICompletionProposal { if (node == null) { node = document.getDocumentElement(); if (node == null) { - return null; + return Collections.emptyList(); } } String desc = String.format("Add ignore '%1$s\' to element", id); Element element = (Element) node; - return new AddSuppressAttribute(editor, id, marker, element, desc); + List<AddSuppressAttribute> fixes = Lists.newArrayListWithExpectedSize(2); + fixes.add(new AddSuppressAttribute(editor, id, marker, element, desc, null)); + + int api = -1; + if (id.equals(ApiDetector.UNSUPPORTED.getId())) { + String message = marker.getAttribute(IMarker.MESSAGE, null); + if (message != null) { + Pattern pattern = Pattern.compile("\\s(\\d+)\\s"); //$NON-NLS-1$ + Matcher matcher = pattern.matcher(message); + if (matcher.find()) { + api = Integer.parseInt(matcher.group(1)); + String targetApi; + String buildCode = LintUtils.getBuildCode(api); + if (buildCode != null) { + targetApi = buildCode.toLowerCase(Locale.US); + fixes.add(new AddSuppressAttribute(editor, id, marker, element, + String.format("Add targetApi '%1$s\' to element", targetApi), + targetApi)); + } + targetApi = Integer.toString(api); + fixes.add(new AddSuppressAttribute(editor, id, marker, element, + String.format("Add targetApi '%1$s\' to element", targetApi), + targetApi)); + } + } + } + + return fixes; } /** @@ -170,7 +228,7 @@ class AddSuppressAttribute implements ICompletionProposal { node = node.getOwnerDocument().getDocumentElement(); String desc = String.format("Add ignore '%1$s\' to element", id); Element element = (Element) node; - return new AddSuppressAttribute(editor, id, marker, element, desc); + return new AddSuppressAttribute(editor, id, marker, element, desc, null); } return null; 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 4c356b7..22fe23b 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 @@ -189,11 +189,7 @@ public class LintFixGenerator implements IMarkerResolutionGenerator2, IQuickAssi String message = marker.getAttribute(IMarker.MESSAGE, null); proposals.add(new MoreInfoProposal(id, message)); - ICompletionProposal fix = AddSuppressAttribute.createFix(editor, marker, id); - if (fix != null) { - proposals.add(fix); - } - + proposals.addAll(AddSuppressAttribute.createFixes(editor, marker, id)); proposals.add(new SuppressProposal(file, id, false)); proposals.add(new SuppressProposal(file.getProject(), id, true /* all */)); proposals.add(new SuppressProposal(file, id, true /* all */)); @@ -296,11 +292,11 @@ public class LintFixGenerator implements IMarkerResolutionGenerator2, IQuickAssi assert isXml; if (part instanceof AndroidXmlEditor) { AndroidXmlEditor editor = (AndroidXmlEditor) part; - AddSuppressAttribute fix = AddSuppressAttribute.createFix(editor, + List<AddSuppressAttribute> fixes = AddSuppressAttribute.createFixes(editor, marker, id); - if (fix != null) { + if (fixes.size() > 0) { IStructuredDocument document = editor.getStructuredDocument(); - fix.apply(document); + fixes.get(0).apply(document); } } } @@ -511,7 +507,7 @@ public class LintFixGenerator implements IMarkerResolutionGenerator2, IQuickAssi @Override public String getDisplayString() { - return "Explain Issue"; + return String.format("Explain Issue (%1$s)", mId); } // ---- Implements MarkerResolution2 ---- diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java index c0d5a85..44c0dc2 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java @@ -755,4 +755,40 @@ public class LintUtils { return imported; } + + /** + * Returns the applicable build code (for + * {@code android.os.Build.VERSION_CODES}) for the corresponding API level, + * or null if it's unknown. + * + * @param api the API level to look up a version code for + * @return the corresponding build code field name, or null + */ + @Nullable + public static String getBuildCode(int api) { + // See http://developer.android.com/reference/android/os/Build.VERSION_CODES.html + switch (api) { + case 1: return "BASE"; //$NON-NLS-1$ + case 2: return "BASE_1_1"; //$NON-NLS-1$ + case 3: return "CUPCAKE"; //$NON-NLS-1$ + case 4: return "DONUT"; //$NON-NLS-1$ + case 5: return "ECLAIR"; //$NON-NLS-1$ + case 6: return "ECLAIR_0_1"; //$NON-NLS-1$ + case 7: return "ECLAIR_MR1"; //$NON-NLS-1$ + case 8: return "FROYO"; //$NON-NLS-1$ + case 9: return "GINGERBREAD"; //$NON-NLS-1$ + case 10: return "GINGERBREAD_MR1"; //$NON-NLS-1$ + case 11: return "HONEYCOMB"; //$NON-NLS-1$ + case 12: return "HONEYCOMB_MR1"; //$NON-NLS-1$ + case 13: return "HONEYCOMB_MR2"; //$NON-NLS-1$ + 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$ + case 17: return "JELLY_BEAN_MR1"; //$NON-NLS-1$ + // If you add more versions here, also update AdtUtils#getAndroidName and + // SdkConstants#HIGHEST_KNOWN_API + } + + return null; + } } 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 fd7bba9..7129b9a 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 @@ -19,14 +19,17 @@ package com.android.tools.lint.checks; import static com.android.SdkConstants.ANDROID_PREFIX; import static com.android.SdkConstants.ANDROID_THEME_PREFIX; import static com.android.SdkConstants.ATTR_CLASS; +import static com.android.SdkConstants.ATTR_TARGET_API; import static com.android.SdkConstants.CONSTRUCTOR_NAME; import static com.android.SdkConstants.TARGET_API; +import static com.android.SdkConstants.TOOLS_URI; import static com.android.SdkConstants.VIEW_TAG; import static com.android.tools.lint.detector.api.LintUtils.getNextInstruction; import static com.android.tools.lint.detector.api.Location.SearchDirection.BACKWARD; import static com.android.tools.lint.detector.api.Location.SearchDirection.FORWARD; import static com.android.tools.lint.detector.api.Location.SearchDirection.NEAREST; +import com.android.SdkConstants; import com.android.annotations.NonNull; import com.android.resources.ResourceFolderType; import com.android.tools.lint.client.api.LintDriver; @@ -35,6 +38,7 @@ import com.android.tools.lint.detector.api.ClassContext; 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.LintUtils; import com.android.tools.lint.detector.api.Location; import com.android.tools.lint.detector.api.Location.SearchHints; import com.android.tools.lint.detector.api.ResourceXmlDetector; @@ -88,7 +92,10 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc "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 " + - "file's minimum SDK as the required API level.", + "file's minimum SDK as the required API level.\n" + + "\n" + + "Similarly, you can use tools:targetApi=\"11\" in an XML file to indicate that " + + "the element will only be inflated in an adequate context.", Category.CORRECTNESS, 6, Severity.ERROR, @@ -168,7 +175,8 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc } int api = mApiDatabase.getFieldVersion(owner, name); int minSdk = getMinSdk(context); - if (api > minSdk && api > context.getFolderVersion()) { + if (api > minSdk && api > context.getFolderVersion() + && api > getLocalMinSdk(attribute.getOwnerElement())) { Location location = context.getLocation(attribute); String message = String.format( "%1$s requires API level %2$d (current min is %3$d)", @@ -210,7 +218,8 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc } int api = mApiDatabase.getFieldVersion(owner, name); int minSdk = getMinSdk(context); - if (api > minSdk && api > context.getFolderVersion()) { + if (api > minSdk && api > context.getFolderVersion() + && api > getLocalMinSdk(element)) { Location location = context.getLocation(textNode); String message = String.format( "%1$s requires API level %2$d (current min is %3$d)", @@ -243,7 +252,8 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc // "(Landroid/content/Context;Landroid/util/AttributeSet;I)V"); //$NON-NLS-1$ "(Landroid/content/Context;)"); //$NON-NLS-1$ int minSdk = getMinSdk(context); - if (api > minSdk && api > context.getFolderVersion()) { + if (api > minSdk && api > context.getFolderVersion() + && api > getLocalMinSdk(element)) { Location location = context.getLocation(element); String message = String.format( "View requires API level %1$d (current min is %2$d): <%3$s>", @@ -650,7 +660,7 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc * @return the API level to use for this node, or -1 */ @SuppressWarnings({"unchecked", "rawtypes"}) - private int getLocalMinSdk(List annotations) { + private static int getLocalMinSdk(List annotations) { if (annotations != null) { for (AnnotationNode annotation : (List<AnnotationNode>)annotations) { String desc = annotation.desc; @@ -680,6 +690,44 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc return -1; } + /** + * Returns the minimum SDK to use in the given element context, or -1 if no + * {@code tools:targetApi} attribute was found. + * + * @param element the element to look at, including parents + * @return the API level to use for this element, or -1 + */ + private int getLocalMinSdk(@NonNull Element element) { + while (element != null) { + String targetApi = element.getAttributeNS(TOOLS_URI, ATTR_TARGET_API); + if (targetApi != null && !targetApi.isEmpty()) { + if (Character.isDigit(targetApi.charAt(0))) { + try { + return Integer.parseInt(targetApi); + } catch (NumberFormatException nufe) { + break; + } + } + + for (int api = 1; api < SdkConstants.HIGHEST_KNOWN_API; api++) { + String code = LintUtils.getBuildCode(api); + if (code != null && code.equalsIgnoreCase(targetApi)) { + return api; + } + } + } + + Node parent = element.getParentNode(); + if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE) { + element = (Element) parent; + } else { + break; + } + } + + return -1; + } + private void report(final ClassContext context, String message, AbstractInsnNode node, MethodNode method, String patternStart, String patternEnd, SearchHints hints) { int lineNumber = node != null ? ClassContext.findLineNumber(node) : -1; diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/MainTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/MainTest.java index d015a3d..ba31ed8 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/MainTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/MainTest.java @@ -139,6 +139,9 @@ public class MainTest extends AbstractCheckTest { "@TargetApi(11), such that this check considers 11 rather than your manifest\n" + "file's minimum SDK as the required API level.\n" + "\n" + + "Similarly, you can use tools:targetApi=\"11\" in an XML file to indicate that\n" + + "the element will only be inflated in an adequate context.\n" + + "\n" + "\n", // Expected error diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiDetectorTest.java index 3ef09aa..9823f23 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiDetectorTest.java @@ -72,6 +72,16 @@ public class ApiDetectorTest extends AbstractCheckTest { )); } + public void testXmlApi1TargetApi() throws Exception { + assertEquals( + "No warnings.", + + lintProject( + "apicheck/minsdk1.xml=>AndroidManifest.xml", + "apicheck/layout_targetapi.xml=>res/layout/layout.xml" + )); + } + public void testXmlApiFolderVersion11() throws Exception { assertEquals( "res/color-v11/colors.xml:9: Error: @android:color/holo_red_light requires API level 14 (current min is 1) [NewApi]\n" + diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/layout_targetapi.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/layout_targetapi.xml new file mode 100644 index 0000000..51ce945 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/layout_targetapi.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="fill_parent" + android:layout_height="match_parent" + android:orientation="vertical" + tools:targetApi="11" > + + <!-- Requires API 5 --> + + <QuickContactBadge + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <!-- Requires API 11 --> + + <CalendarView + android:layout_width="fill_parent" + android:layout_height="fill_parent" /> + + <!-- Requires API 14 --> + + <GridLayout + foo="@android:attr/actionBarSplitStyle" + bar="@android:color/holo_red_light" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + tools:targetApi="ICE_CREAM_SANDWICH" > + + <Button + android:layout_width="fill_parent" + android:layout_height="fill_parent" /> + </GridLayout> + +</LinearLayout> |