diff options
6 files changed, 188 insertions, 1 deletions
diff --git a/common/src/com/android/SdkConstants.java b/common/src/com/android/SdkConstants.java index 0690a70..1a8a61c 100644 --- a/common/src/com/android/SdkConstants.java +++ b/common/src/com/android/SdkConstants.java @@ -811,6 +811,8 @@ public final class SdkConstants { // Menus public static final String ATTR_SHOW_AS_ACTION = "showAsAction"; //$NON-NLS-1$ + public static final String ATTR_TITLE = "title"; //$NON-NLS-1$ + public static final String ATTR_VISIBLE = "visible"; //$NON-NLS-1$ public static final String VALUE_IF_ROOM = "ifRoom"; //$NON-NLS-1$ public static final String VALUE_ALWAYS = "always"; //$NON-NLS-1$ diff --git a/eclipse/dictionary.txt b/eclipse/dictionary.txt index d84f60d..af86ba9 100644 --- a/eclipse/dictionary.txt +++ b/eclipse/dictionary.txt @@ -90,6 +90,7 @@ drawables dropdown ed editable +em endian endpoint enum 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 16a5686..97df003 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 @@ -55,7 +55,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { private static final List<Issue> sIssues; static { - final int initialCapacity = 117; + final int initialCapacity = 118; List<Issue> issues = new ArrayList<Issue>(initialCapacity); issues.add(AccessibilityDetector.ISSUE); @@ -163,6 +163,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { issues.add(NamespaceDetector.UNUSED); issues.add(NamespaceDetector.TYPO); issues.add(AlwaysShowActionDetector.ISSUE); + issues.add(TitleDetector.ISSUE); issues.add(ColorUsageDetector.ISSUE); issues.add(JavaPerformanceDetector.PAINT_ALLOC); issues.add(JavaPerformanceDetector.USE_VALUEOF); diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TitleDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TitleDetector.java new file mode 100644 index 0000000..1d1d024 --- /dev/null +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TitleDetector.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2012 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.checks; + +import static com.android.SdkConstants.ANDROID_URI; +import static com.android.SdkConstants.ATTR_TITLE; +import static com.android.SdkConstants.ATTR_VISIBLE; +import static com.android.SdkConstants.TAG_ITEM; +import static com.android.SdkConstants.VALUE_FALSE; + +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.resources.ResourceFolderType; +import com.android.tools.lint.detector.api.Category; +import com.android.tools.lint.detector.api.Detector.JavaScanner; +import com.android.tools.lint.detector.api.Issue; +import com.android.tools.lint.detector.api.ResourceXmlDetector; +import com.android.tools.lint.detector.api.Scope; +import com.android.tools.lint.detector.api.Severity; +import com.android.tools.lint.detector.api.Speed; +import com.android.tools.lint.detector.api.XmlContext; + +import org.w3c.dom.Element; + +import java.util.Collection; +import java.util.Collections; + +/** + * Check which makes sure menu items specify a title + */ +public class TitleDetector extends ResourceXmlDetector implements JavaScanner { + /** The main issue discovered by this detector */ + public static final Issue ISSUE = Issue.create( + "MenuTitle", //$NON-NLS-1$ + "Ensures that all menu items supply a title", + + "From the action bar documentation:\n" + + // u2014: em dash + "\"It's important that you always define android:title for each menu item \u2014 " + + "even if you don't declare that the title appear with the action item \u2014 for " + + "three reasons:\n" + + "\n" + + "* If there's not enough room in the action bar for the action item, the menu " + + "item appears in the overflow menu and only the title appears.\n" + + "* Screen readers for sight-impaired users read the menu item's title.\n" + + "* If the action item appears with only the icon, a user can long-press the item " + + "to reveal a tool-tip that displays the action item's title.\n" + + "The android:icon is always optional, but recommended.", + + Category.USABILITY, + 5, + Severity.WARNING, + TitleDetector.class, + Scope.RESOURCE_FILE_SCOPE).setMoreInfo( + "http://developer.android.com/guide/topics/ui/actionbar.html"); //$NON-NLS-1$ + + /** Constructs a new {@link TitleDetector} */ + public TitleDetector() { + } + + @Override + public boolean appliesTo(@NonNull ResourceFolderType folderType) { + return folderType == ResourceFolderType.MENU; + } + + @Override + public @NonNull Speed getSpeed() { + return Speed.FAST; + } + + @Override + @Nullable + public Collection<String> getApplicableElements() { + return Collections.singletonList(TAG_ITEM); + } + + @Override + public void visitElement(@NonNull XmlContext context, @NonNull Element element) { + if (element.hasAttributeNS(ANDROID_URI, ATTR_TITLE)) { + return; + } + + // TODO: Find out if this is necessary on older versions too. + // I swear I saw it mentioned. + if (context.getMainProject().getTargetSdk() < 11) { + return; + } + + if (VALUE_FALSE.equals(element.getAttributeNS(ANDROID_URI, ATTR_VISIBLE))) { + return; + } + + String message = "Menu items should specify a title"; + context.report(ISSUE, element, context.getLocation(element), message, null); + } +} diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TitleDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TitleDetectorTest.java new file mode 100644 index 0000000..7259cde --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TitleDetectorTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2012 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.checks; + +import com.android.tools.lint.detector.api.Detector; + +@SuppressWarnings("javadoc") +public class TitleDetectorTest extends AbstractCheckTest { + @Override + protected Detector getDetector() { + return new TitleDetector(); + } + + public void test() throws Exception { + assertEquals( + "res/menu/titles.xml:3: Warning: Menu items should specify a title [MenuTitle]\n" + + " <item android:id=\"@+id/action_bar_progress_spinner\"\n" + + " ^\n" + + "res/menu/titles.xml:12: Warning: Menu items should specify a title [MenuTitle]\n" + + " <item android:id=\"@+id/menu_plus_one\"\n" + + " ^\n" + + "0 errors, 2 warnings\n", + + lintProject( + "apicheck/minsdk14.xml=>AndroidManifest.xml", + "res/menu/titles.xml")); + } + + public void testOk() throws Exception { + assertEquals( + "No warnings.", + + lintProject( + "apicheck/minsdk1.xml=>AndroidManifest.xml", + "res/menu/titles.xml")); + } + + public void testOk2() throws Exception { + assertEquals( + "No warnings.", + + lintProject("res/menu-land/actions.xml")); + } +} diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/menu/titles.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/menu/titles.xml new file mode 100644 index 0000000..a1ae5bb --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/menu/titles.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/action_bar_progress_spinner" + android:showAsAction="always" + android:background="@null" + android:selectableItemBackground="@null" + android:actionLayout="@layout/action_bar_progress_spinner_layout"/> + <item android:id="@+id/refresh" + android:title="@string/menu_refresh" + android:showAsAction="always" + android:icon="@drawable/ic_menu_refresh"/> + <item android:id="@+id/menu_plus_one" + android:showAsAction="always" + android:icon="@drawable/ic_menu_plus1"/> +</menu> |