diff options
28 files changed, 351 insertions, 138 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml index 5979f74..ad8c899 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml +++ b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml @@ -467,7 +467,7 @@ label="Fix Project Properties" menubarPath="com.android.ide.eclipse.adt.AndroidTools/group3" /> <action - class="com.android.ide.eclipse.adt.internal.actions.AddCompatibilityJarAction" + class="com.android.ide.eclipse.adt.internal.actions.AddSupportJarAction" enablesFor="1" icon="icons/android.png" id="com.android.ide.eclipse.adt.wizards.actions.AddCompatibilityJarAction" diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/AddCompatibilityJarAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/AddSupportJarAction.java index 1d84ad2..5a0c13f 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/AddCompatibilityJarAction.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/AddSupportJarAction.java @@ -68,7 +68,7 @@ import java.util.Iterator; import java.util.Map; /** - * An action to add the android-support-v4.jar compatibility library + * An action to add the android-support-v4.jar support library * to the selected project. * <p/> * This should be used by the GLE. The action itself is currently more @@ -76,10 +76,14 @@ import java.util.Map; * <p/> * TODO: make this more configurable. */ -public class AddCompatibilityJarAction implements IObjectActionDelegate { - - private static final String FD_ANDROID = "android"; //$NON-NLS-1$ - private static final String FD_SUPPORT = "support"; //$NON-NLS-1$ +public class AddSupportJarAction implements IObjectActionDelegate { + + /** The vendor ID of the support library. */ + private static final String VENDOR_ID = "android"; //$NON-NLS-1$ + /** The path ID of the support library. */ + private static final String SUPPORT_ID = "support"; //$NON-NLS-1$ + /** The path ID of the compatibility library (which was its id for releases 1-3). */ + private static final String COMPATIBILITY_ID = "compatibility"; //$NON-NLS-1$ private static final String FD_GRIDLAYOUT = "gridlayout"; //$NON-NLS-1$ private static final String FD_V7 = "v7"; //$NON-NLS-1$ private static final String FD_V4 = "v4"; //$NON-NLS-1$ @@ -120,9 +124,9 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { } /** - * Install the compatibility jar into the given project. + * Install the support jar into the given project. * - * @param project The Android project to install the compatibility jar into + * @param project The Android project to install the support jar into * @return true if the installation was successful */ public static boolean install(final IProject project) { @@ -157,16 +161,16 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { final Sdk sdk = Sdk.getCurrent(); if (sdk == null) { AdtPlugin.printErrorToConsole( - AddCompatibilityJarAction.class.getSimpleName(), // tag + AddSupportJarAction.class.getSimpleName(), // tag "Error: Android SDK is not loaded yet."); //$NON-NLS-1$ return null; } String sdkLocation = sdk.getSdkLocation(); if (minimumRevision > 0) { - File path = getCompatJarFile(); + File path = getSupportJarFile(); if (path != null) { - assert path.exists(); // guaranteed by the getCompatJarFile call + assert path.exists(); // guaranteed by the getSupportJarFile call int installedRevision = getInstalledRevision(); if (installedRevision != -1 && minimumRevision <= installedRevision) { return path; @@ -184,14 +188,13 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { new AdtConsoleSdkLog(), sdkLocation); - Pair<Boolean, File> result = window.installExtraPackage( - FD_ANDROID, FD_SUPPORT); + Pair<Boolean, File> result = window.installExtraPackage(VENDOR_ID, SUPPORT_ID); // TODO: Make sure the version is at the required level; we know we need at least one // containing the v7 support if (!result.getFirst().booleanValue()) { - AdtPlugin.printErrorToConsole("Failed to install Android Compatibility library"); + AdtPlugin.printErrorToConsole("Failed to install Android Support library"); return null; } @@ -203,7 +206,7 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { final File jarPath = new File(path, ANDROID_SUPPORT_V4_JAR); if (!jarPath.isFile()) { - AdtPlugin.printErrorToConsole("Android Compatibility JAR not found:", + AdtPlugin.printErrorToConsole("Android Support Jar not found:", jarPath.getAbsolutePath()); return null; } @@ -212,7 +215,7 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { } /** - * Returns the installed revision number of the Android Compatibility + * Returns the installed revision number of the Android Support * library, or -1 if the package is not installed. * * @return the installed revision number, or -1 @@ -223,7 +226,13 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { String sdkLocation = sdk.getSdkLocation(); SdkManager manager = SdkManager.createManager(sdkLocation, new NullSdkLog()); Map<String, Integer> versions = manager.getExtrasVersions(); - Integer version = versions.get("android/support"); //$NON-NLS-1$ + Integer version = versions.get(VENDOR_ID + '/' + SUPPORT_ID); + if (version == null) { + // Check the old compatibility library. When the library is updated in-place + // the manager doesn't change its folder name (since that is a source of + // endless issues on Windows.) + version = versions.get(VENDOR_ID + '/' + COMPATIBILITY_ID); + } if (version != null) { return version.intValue(); } @@ -235,7 +244,7 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { /** * Similar to {@link #install}, but rather than copy a jar into the given * project, it creates a new library project in the workspace for the - * compatibility library, and adds a library dependency on the newly + * support library, and adds a library dependency on the newly * installed library from the given project. * * @param project the project to add a dependency on the library to @@ -249,7 +258,7 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { final IJavaProject javaProject = JavaCore.create(project); if (javaProject != null) { - File supportPath = getCompatPackageDir(); + File supportPath = getSupportPackageDir(); if (!supportPath.isDirectory()) { File path = installSupport(8); // GridLayout arrived in rev 7 and fixed in rev 8 if (path == null) { @@ -281,28 +290,53 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { /** * Returns the directory containing the support libraries (v4, v7, v13, * ...), which may or may not exist + * + * @return a path to the support library or null */ - private static File getCompatPackageDir() { - File sdk = new File(Sdk.getCurrent().getSdkLocation()); - File supportPath = new File(sdk, - SdkConstants.FD_EXTRAS + File.separator - + FD_ANDROID + File.separator - + FD_SUPPORT); - return supportPath; + private static File getSupportPackageDir() { + final Sdk sdk = Sdk.getCurrent(); + if (sdk != null) { + String sdkLocation = sdk.getSdkLocation(); + SdkManager manager = SdkManager.createManager(sdkLocation, new NullSdkLog()); + Map<String, Integer> versions = manager.getExtrasVersions(); + Integer version = versions.get(VENDOR_ID + '/' + SUPPORT_ID); + if (version != null) { + File supportPath = new File(sdkLocation, + SdkConstants.FD_EXTRAS + File.separator + + VENDOR_ID + File.separator + + SUPPORT_ID); + return supportPath; + } + + // Check the old compatibility library. When the library is updated in-place + // the manager doesn't change its folder name (since that is a source of + // endless issues on Windows.) + version = versions.get(VENDOR_ID + '/' + COMPATIBILITY_ID); + if (version != null) { + File supportPath = new File(sdkLocation, + SdkConstants.FD_EXTRAS + File.separator + + VENDOR_ID + File.separator + + COMPATIBILITY_ID); + return supportPath; + } + } + return null; } /** - * Returns a path to the installed jar file for the compatibility library, + * Returns a path to the installed jar file for the support library, * or null if it does not exist * - * @return a path to the library or null + * @return a path to the v4.jar or null */ @Nullable - public static File getCompatJarFile() { - File supportDir = getCompatPackageDir(); - File path = new File(supportDir, FD_V4 + File.separator + ANDROID_SUPPORT_V4_JAR); - if (path.exists()) { - return path; + public static File getSupportJarFile() { + File supportDir = getSupportPackageDir(); + if (supportDir != null) { + File path = new File(supportDir, FD_V4 + File.separator + ANDROID_SUPPORT_V4_JAR); + if (path.exists()) { + return path; + } } return null; @@ -323,7 +357,7 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { boolean waitForFinish) { // Install a new library into the workspace. This is a copy rather than - // a reference to the compatibility library version such that modifications + // a reference to the support library version such that modifications // do not modify the pristine copy in the SDK install area. final IProject newProject; @@ -390,7 +424,7 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate { // Now add library dependency // Run an Eclipse asynchronous job to update the project - Job job = new Job("Add Compatibility Library Dependency to Project") { + Job job = new Job("Add Support Library Dependency to Project") { @Override protected IStatus run(IProgressMonitor monitor) { try { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureAssetSetPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureAssetSetPage.java index 0c9e5b7..132943b 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureAssetSetPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureAssetSetPage.java @@ -587,7 +587,7 @@ public class ConfigureAssetSetPage extends WizardPage implements SelectionListen chooseForegroundTab(mClipartRadio, mClipartForm); mChooseClipart.setFocus(); } else if (sourceType == CreateAssetSetWizardState.SourceType.TEXT) { - updateFontLabel(mFontButton.getFont()); + updateFontLabel(); chooseForegroundTab(mTextRadio, mTextForm); mText.setFocus(); } @@ -681,7 +681,7 @@ public class ConfigureAssetSetPage extends WizardPage implements SelectionListen chooseForegroundTab((Button) source, mClipartForm); } else if (source == mTextRadio) { mValues.sourceType = CreateAssetSetWizardState.SourceType.TEXT; - updateFontLabel(mFontButton.getFont()); + updateFontLabel(); chooseForegroundTab((Button) source, mTextForm); mText.setFocus(); } @@ -769,7 +769,6 @@ public class ConfigureAssetSetPage extends WizardPage implements SelectionListen chooserForm.setLayout(clipartFormLayout); MouseAdapter clickListener = new MouseAdapter() { - @SuppressWarnings("unused") @Override public void mouseDown(MouseEvent event) { // Clicked on some of the sample art @@ -838,7 +837,8 @@ public class ConfigureAssetSetPage extends WizardPage implements SelectionListen FontDialog dialog = new FontDialog(mFontButton.getShell()); FontData[] fontList; if (mFontButton.getData() == null) { - fontList = mFontButton.getDisplay().getFontList("Helvetica", true /*scalable*/); + fontList = mFontButton.getDisplay().getFontList( + mValues.getTextFont().getFontName(), true /*scalable*/); } else { fontList = mFontButton.getFont().getFontData(); } @@ -847,11 +847,26 @@ public class ConfigureAssetSetPage extends WizardPage implements SelectionListen if (data != null) { Font font = new Font(mFontButton.getDisplay(), dialog.getFontList()); mFontButton.setFont(font); - updateFontLabel(font); + mFontButton.setData(font); + + // Always use a large font for the rendering, even though user is typically + // picking small font sizes in the font chooser + //int dpi = mFontButton.getDisplay().getDPI().y; + //int height = (int) Math.round(fontData.getHeight() * dpi / 72.0); + int fontHeight = new TextRenderUtil.Options().fontSize; + FontData fontData = font.getFontData()[0]; + int awtStyle = java.awt.Font.PLAIN; + int swtStyle = fontData.getStyle(); + if ((swtStyle & SWT.ITALIC) != 0) { + awtStyle |= java.awt.Font.ITALIC; + } + if ((swtStyle & SWT.BOLD) != 0) { + awtStyle = java.awt.Font.BOLD; + } + mValues.setTextFont(new java.awt.Font(fontData.getName(), awtStyle, fontHeight)); + + updateFontLabel(); mFontButton.getParent().pack(); - // Mark the font on the button as custom (since the renderer needs to - // distinguish between this font and the default font it starts out with) - mFontButton.setData(Boolean.TRUE); } } @@ -907,41 +922,8 @@ public class ConfigureAssetSetPage extends WizardPage implements SelectionListen } } - private void updateFontLabel(Font f) { - FontData[] fd = f.getFontData(); - FontData primary = fd[0]; - String description = String.format("%1$s", primary.getName()); - mFontButton.setText(description); - } - - private java.awt.Font getSelectedFont() { - // Always use a large font for the rendering, even though user is typically - // picking small font sizes in the font chooser - //int dpi = mFontButton.getDisplay().getDPI().y; - //int height = (int) Math.round(fontData.getHeight() * dpi / 72.0); - int fontHeight = new TextRenderUtil.Options().fontSize; - - if (mFontButton.getData() == null) { - // The user has not yet picked a font; look up the default font to use - // (Helvetica Bold, not whatever font happened to be used for button widgets - // in SWT on this platform) - return new java.awt.Font("Helvetica", java.awt.Font.BOLD, fontHeight); //$NON-NLS-1$ - } - - Font font = mFontButton.getFont(); - FontData fontData = font.getFontData()[0]; - - int awtStyle = java.awt.Font.PLAIN; - int swtStyle = fontData.getStyle(); - - if ((swtStyle & SWT.ITALIC) != 0) { - awtStyle |= java.awt.Font.ITALIC; - } - if ((swtStyle & SWT.BOLD) != 0) { - awtStyle = java.awt.Font.BOLD; - } - - return new java.awt.Font(fontData.getName(), awtStyle, fontHeight); + private void updateFontLabel() { + mFontButton.setText(mValues.getTextFont().getFontName()); } private int getPadding() { @@ -1089,7 +1071,7 @@ public class ConfigureAssetSetPage extends WizardPage implements SelectionListen case TEXT: { String text = mValues.text; TextRenderUtil.Options options = new TextRenderUtil.Options(); - options.font = getSelectedFont(); + options.font = mValues.getTextFont(); int color; if (type.needsColors()) { color = 0xFF000000 diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizardState.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizardState.java index 62176ca..571c6f2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizardState.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizardState.java @@ -15,11 +15,14 @@ */ package com.android.ide.eclipse.adt.internal.assetstudio; +import com.android.annotations.NonNull; import com.android.assetstudiolib.GraphicGenerator.Shape; import org.eclipse.core.resources.IProject; import org.eclipse.swt.graphics.RGB; +import java.awt.Font; +import java.awt.GraphicsEnvironment; import java.io.File; /** @@ -78,6 +81,53 @@ public class CreateAssetSetWizardState { /** The background color to use for the text or clipart (unless shape is {@link Shape#NONE} */ public RGB foreground = new RGB(0x00, 0x00, 0x00); + /** If {@link #sourceType} is a {@link SourceType#TEXT}, the font of the text to render */ + private Font mTextFont; + + /** + * Gets the text font to be used for text rendering if the + * {@link #sourceType} is a {@link SourceType#TEXT} + * + * @return the text font + */ + @NonNull + public Font getTextFont() { + if (mTextFont == null) { + GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); + String[] fontNames = env.getAvailableFontFamilyNames(); + for (String familyName : fontNames) { + if (familyName.equals("Helvetica")) { + mTextFont = new java.awt.Font(familyName, java.awt.Font.BOLD, 512); + break; + } + } + if (mTextFont == null) { + for (String familyName : fontNames) { + if (familyName.equals("Arial")) { + mTextFont = new java.awt.Font(familyName, java.awt.Font.BOLD, 512); + break; + } + } + + if (mTextFont == null) { + mTextFont = new java.awt.Font("SansSerif", java.awt.Font.BOLD, 512); + } + } + } + + return mTextFont; + } + + /** + * Sets the text font to be used for text rendering if the + * {@link #sourceType} is a {@link SourceType#TEXT} + * + * @param textFont the font to use + */ + public void setTextFont(@NonNull Font textFont) { + mTextFont = textFont; + } + /** Types of sources that the asset studio can use to generate icons from */ public enum SourceType { /** Generate the icon using the image pointed to by {@link #imagePath} */ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java index 60f8365..c33384d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java @@ -36,7 +36,7 @@ import com.android.ide.common.api.Rect; import com.android.ide.common.layout.BaseViewRule; import com.android.ide.common.resources.ResourceRepository; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.actions.AddCompatibilityJarAction; +import com.android.ide.eclipse.adt.internal.actions.AddSupportJarAction; import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate; @@ -406,7 +406,7 @@ class ClientRulesEngine implements IClientRulesEngine { 1 /* default button: Cancel */); int answer = dialog.open(); if (answer == 0) { - if (!AddCompatibilityJarAction.install(project)) { + if (!AddSupportJarAction.install(project)) { return null; } } else { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java index 3cd9729..8479219 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java @@ -39,7 +39,7 @@ import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElement import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.project.CompatibilityLibraryHelper; +import com.android.ide.eclipse.adt.internal.project.SupportLibraryHelper; import org.eclipse.swt.graphics.Rectangle; import org.w3c.dom.NamedNodeMap; @@ -267,7 +267,7 @@ public class NodeProxy implements INode { if (editor != null) { // Possibly replace the tag with a compatibility version if the // minimum SDK requires it - viewFqcn = CompatibilityLibraryHelper.getTagFor(editor.getProject(), viewFqcn); + viewFqcn = SupportLibraryHelper.getTagFor(editor.getProject(), viewFqcn); } // Find the descriptor for this FQCN 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 353ecb7..f5d3711 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 @@ -59,7 +59,6 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.compiler.CategorizedProblem; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; @@ -961,24 +960,10 @@ public class EclipseLintClient extends LintClient implements IDomParser { try { unit = mParser.parse(sourceUnit, compilationResult); } catch (AbortCompilation e) { - - String message; - Location location; - if (e.problem != null) { - CategorizedProblem problem = e.problem; - message = problem.getMessage(); - location = Location.create(context.file, - new DefaultPosition(problem.getSourceLineNumber() - 1, -1, - problem.getSourceStart()), - new DefaultPosition(problem.getSourceLineNumber() - 1, -1, - problem.getSourceEnd())); - } else { - location = Location.create(context.file); - message = e.getCause() != null ? e.getCause().getLocalizedMessage() : - e.getLocalizedMessage(); - } - - context.report(IssueRegistry.PARSER_ERROR, location, message, null); + // No need to report Java parsing errors while running in Eclipse. + // Eclipse itself will already provide problem markers for these files, + // so all this achieves is creating "multiple annotations on this line" + // tooltips instead. return null; } if (unit == null) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java index d3bb87b..9fa5018 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java @@ -150,7 +150,7 @@ abstract class LintFix implements ICompletionProposal { sFixes.put(HardcodedValuesDetector.ISSUE.getId(), ExtractStringFix.class); sFixes.put(UselessViewDetector.USELESS_LEAF.getId(), RemoveUselessViewFix.class); sFixes.put(UselessViewDetector.USELESS_PARENT.getId(), RemoveUselessViewFix.class); - sFixes.put(PxUsageDetector.ISSUE.getId(), ConvertToDpFix.class); + sFixes.put(PxUsageDetector.PX_ISSUE.getId(), ConvertToDpFix.class); sFixes.put(TextFieldDetector.ISSUE.getId(), SetAttributeFix.class); sFixes.put(SecurityDetector.EXPORTED_SERVICE.getId(), SetAttributeFix.class); sFixes.put(DetectMissingPrefix.MISSING_NAMESPACE.getId(), AddPrefixFix.class); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/CompatibilityLibraryHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/SupportLibraryHelper.java index d5f5c3c..35bc2a9 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/CompatibilityLibraryHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/SupportLibraryHelper.java @@ -24,7 +24,7 @@ import static com.android.ide.common.layout.LayoutConstants.FQCN_SPACE_V7; import com.android.annotations.NonNull; import com.android.annotations.Nullable; import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.actions.AddCompatibilityJarAction; +import com.android.ide.eclipse.adt.internal.actions.AddSupportJarAction; import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo; import com.android.ide.eclipse.adt.internal.sdk.ProjectState; import com.android.ide.eclipse.adt.internal.sdk.ProjectState.LibraryState; @@ -44,7 +44,7 @@ import org.eclipse.swt.widgets.Display; * {@code <GridLayout>} into {@code <com.android.support.v7.GridLayout>} if it * does not. */ -public class CompatibilityLibraryHelper { +public class SupportLibraryHelper { /** * Returns the correct tag to use for the given view tag. This is normally * the same as the tag itself. However, for some views which are not available @@ -113,7 +113,7 @@ public class CompatibilityLibraryHelper { if (answer == 0) { if (supportProject != null) { // Just add library dependency - if (!AddCompatibilityJarAction.addLibraryDependency( + if (!AddSupportJarAction.addLibraryDependency( supportProject, project, true /* waitForFinish */)) { @@ -121,7 +121,7 @@ public class CompatibilityLibraryHelper { } } else { // Install library AND add dependency - if (!AddCompatibilityJarAction.installGridLayoutLibrary( + if (!AddSupportJarAction.installGridLayoutLibrary( project, true /* waitForFinish */)) { return tag; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java index 815848e..04d149a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java @@ -31,7 +31,7 @@ import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle; import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter; import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo; import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; -import com.android.ide.eclipse.adt.internal.project.CompatibilityLibraryHelper; +import com.android.ide.eclipse.adt.internal.project.SupportLibraryHelper; import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileCreationPage.TypeInfo; import com.android.resources.ResourceFolderType; import com.android.util.Pair; @@ -210,7 +210,7 @@ public class NewXmlFileWizard extends Wizard implements INewWizard { IProject project = file.getParent().getProject(); int minSdk = ManifestInfo.get(project).getMinSdkVersion(); if (minSdk < 14) { - root = CompatibilityLibraryHelper.getTagFor(project, FQCN_GRID_LAYOUT); + root = SupportLibraryHelper.getTagFor(project, FQCN_GRID_LAYOUT); if (root.equals(FQCN_GRID_LAYOUT)) { root = GRID_LAYOUT; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java index 7f67a0d..a74ffa8 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java @@ -233,12 +233,14 @@ class ActivityPage extends WizardPage implements SelectionListener { private void validatePage() { IStatus status = null; - if (mList.getSelectionCount() < 1) { - status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "Select an activity type"); - } else { - TemplateHandler templateHandler = mValues.activityValues.getTemplateHandler(); - status = templateHandler.validateTemplate(mValues.minSdkLevel); + if (mValues.createActivity) { + if (mList.getSelectionCount() < 1) { + status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, + "Select an activity type"); + } else { + TemplateHandler templateHandler = mValues.activityValues.getTemplateHandler(); + status = templateHandler.validateTemplate(mValues.minSdkLevel); + } } setPageComplete(status == null || status.getSeverity() != IStatus.ERROR); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java index bdd53b8..c5fd617 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java @@ -16,7 +16,7 @@ package com.android.ide.eclipse.adt.internal.wizards.templates; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.actions.AddCompatibilityJarAction; +import com.android.ide.eclipse.adt.internal.actions.AddSupportJarAction; import com.android.util.Pair; import org.eclipse.core.runtime.IStatus; @@ -203,7 +203,7 @@ class InstallDependencyPage extends WizardPage implements SelectionListener { if (SUPPORT_LIBRARY_NAME.equals(sCachedName)) { return sCachedVersion; } else { - int version = AddCompatibilityJarAction.getInstalledRevision(); + int version = AddSupportJarAction.getInstalledRevision(); sCachedName = SUPPORT_LIBRARY_NAME; sCachedVersion = version; return version; @@ -264,21 +264,19 @@ class InstallDependencyPage extends WizardPage implements SelectionListener { sCachedName = null; if (isInstalled()) { showNextPage(); - } else { - updateVersionLabels(); } + updateVersionLabels(); } else if (source == mInstallButton) { sCachedName = null; for (Pair<String, Integer> dependency : mTemplate.getDependencies()) { String name = dependency.getFirst(); if (SUPPORT_LIBRARY_NAME.equals(name)) { int version = dependency.getSecond(); - File installed = AddCompatibilityJarAction.installSupport(version); + File installed = AddSupportJarAction.installSupport(version); if (installed != null) { showNextPage(); - } else { - updateVersionLabels(); } + updateVersionLabels(); } } } else if (source == mLink) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java index 3e4e342..2daf5ed 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java @@ -329,7 +329,11 @@ public class NewProjectPage extends WizardPage } private IAndroidTarget[] getCompilationTargets() { - IAndroidTarget[] targets = Sdk.getCurrent().getTargets(); + Sdk current = Sdk.getCurrent(); + if (current == null) { + return new IAndroidTarget[0]; + } + IAndroidTarget[] targets = current.getTargets(); List<IAndroidTarget> list = new ArrayList<IAndroidTarget>(); for (IAndroidTarget target : targets) { 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 3e5d23d..43ade9c 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 @@ -32,7 +32,7 @@ import com.android.annotations.Nullable; import com.android.ide.eclipse.adt.AdtConstants; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.actions.AddCompatibilityJarAction; +import com.android.ide.eclipse.adt.internal.actions.AddSupportJarAction; import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences; import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle; import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter; @@ -411,7 +411,7 @@ class TemplateHandler { if (dependencyName.equals(SUPPORT_LIBRARY_NAME)) { // We assume the revision requirement has been satisfied // by the wizard - File path = AddCompatibilityJarAction.getCompatJarFile(); + File path = AddSupportJarAction.getSupportJarFile(); if (path != null) { IPath to = getTargetPath(FD_NATIVE_LIBS +'/' + path.getName()); try { @@ -433,6 +433,7 @@ class TemplateHandler { } } + @SuppressWarnings("unused") private boolean canOverwrite(File file) { if (file.exists()) { // Warn that the file already exists and ask the user what to do diff --git a/lint/cli/src/com/android/tools/lint/LintCliXmlParser.java b/lint/cli/src/com/android/tools/lint/LintCliXmlParser.java index 24149b3..8611019 100644 --- a/lint/cli/src/com/android/tools/lint/LintCliXmlParser.java +++ b/lint/cli/src/com/android/tools/lint/LintCliXmlParser.java @@ -72,7 +72,7 @@ public class LintCliXmlParser extends PositionXmlParser implements IDomParser { @Override public @NonNull Location getLocation(@NonNull XmlContext context, @NonNull Node node) { - OffsetPosition pos = (OffsetPosition) getPosition(node, 0, 0); + OffsetPosition pos = (OffsetPosition) getPosition(node, -1, -1); if (pos != null) { return Location.create(context.file, pos, (OffsetPosition) pos.getEnd()); } 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 faccdaf..1ac15e2 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 @@ -19,6 +19,7 @@ package com.android.tools.lint.detector.api; import com.android.annotations.NonNull; import com.android.annotations.Nullable; import com.android.tools.lint.client.api.Configuration; +import com.android.tools.lint.client.api.IssueRegistry; import com.google.common.annotations.Beta; import java.util.ArrayList; @@ -355,6 +356,10 @@ public final class Issue implements Comparable<Issue> { } } + if (this == IssueRegistry.LINT_ERROR || this == IssueRegistry.PARSER_ERROR) { + return true; + } + return false; } 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 3b7d63f..0521e7c 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 @@ -189,6 +189,7 @@ public class LintConstants { public static final String ATTR_AUTO_TEXT = "autoText"; //$NON-NLS-1$ public static final String ATTR_ENABLED = "enabled"; //$NON-NLS-1$ public static final String ATTR_SINGLE_LINE = "singleLine"; //$NON-NLS-1$ + public static final String ATTR_SCALE_TYPE = "scaleType"; //$NON-NLS-1$ // AbsoluteLayout layout params public static final String ATTR_LAYOUT_Y = "layout_y"; //$NON-NLS-1$ 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 cce3238..4ce06f9 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 @@ -47,14 +47,14 @@ public class BuiltinIssueRegistry extends IssueRegistry { /** * Manifest constant for declaring an issue provider. Example: - * Lint-Issues: foo.bar.CustomIssueRegistry + * Lint-Registry: foo.bar.CustomIssueRegistry */ private static final String MF_LINT_REGISTRY = "Lint-Registry"; //$NON-NLS-1$ private static final List<Issue> sIssues; static { - final int initialCapacity = 96; + final int initialCapacity = 97; List<Issue> issues = new ArrayList<Issue>(initialCapacity); issues.add(AccessibilityDetector.ISSUE); @@ -94,7 +94,8 @@ public class BuiltinIssueRegistry extends IssueRegistry { issues.add(Utf8Detector.ISSUE); issues.add(ProguardDetector.WRONGKEEP); issues.add(ProguardDetector.SPLITCONFIG); - issues.add(PxUsageDetector.ISSUE); + issues.add(PxUsageDetector.PX_ISSUE); + issues.add(PxUsageDetector.DP_ISSUE); issues.add(TextFieldDetector.ISSUE); issues.add(TextViewDetector.ISSUE); issues.add(UnusedResourceDetector.ISSUE); @@ -288,7 +289,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { sAdtFixes.add(HardcodedValuesDetector.ISSUE); sAdtFixes.add(UselessViewDetector.USELESS_LEAF); sAdtFixes.add(UselessViewDetector.USELESS_PARENT); - sAdtFixes.add(PxUsageDetector.ISSUE); + sAdtFixes.add(PxUsageDetector.PX_ISSUE); sAdtFixes.add(TextFieldDetector.ISSUE); sAdtFixes.add(SecurityDetector.EXPORTED_SERVICE); sAdtFixes.add(DetectMissingPrefix.MISSING_NAMESPACE); 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 f87abcc..b45709f 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 @@ -30,12 +30,14 @@ import org.w3c.dom.Attr; import java.util.Collection; /** - * Check which looks at the children of ScrollViews and ensures that they fill/match - * the parent width instead of setting wrap_content. + * Check for px dimensions instead of dp dimensions. + * Also look for non-"sp" text sizes. + * <p> + * TODO: Look in themes as well (text node usages). */ public class PxUsageDetector extends LayoutDetector { /** The main issue discovered by this detector */ - public static final Issue ISSUE = Issue.create( + public static final Issue PX_ISSUE = Issue.create( "PxUsage", //$NON-NLS-1$ "Looks for use of the \"px\" dimension", // This description is from the below screen support document @@ -55,6 +57,29 @@ public class PxUsageDetector extends LayoutDetector { Scope.RESOURCE_FILE_SCOPE).setMoreInfo( "http://developer.android.com/guide/practices/screens_support.html#screen-independence"); //$NON-NLS-1$ + /** The main issue discovered by this detector */ + public static final Issue DP_ISSUE = Issue.create( + "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 " + + "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 " + + "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 " + + "to be more flexible.", + Category.CORRECTNESS, + 2, + Severity.WARNING, + PxUsageDetector.class, + Scope.RESOURCE_FILE_SCOPE).setMoreInfo( + "http://developer.android.com/training/multiscreen/screendensities.html"); //$NON-NLS-1$ + /** Constructs a new {@link PxUsageDetector} */ public PxUsageDetector() { } @@ -72,13 +97,22 @@ public class PxUsageDetector extends LayoutDetector { @Override public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) { String value = attribute.getValue(); - if (value.endsWith("px") && value.matches("\\d+px")) { //$NON-NLS-1$ + if (value.endsWith("px") && value.matches("\\d+px")) { //$NON-NLS-1$ //$NON-NLS-2$ if (value.charAt(0) == '0') { // 0px is fine. 0px is 0dp regardless of density... return; } - context.report(ISSUE, attribute, context.getLocation(attribute), + if (context.isEnabled(PX_ISSUE)) { + context.report(PX_ISSUE, attribute, context.getLocation(attribute), "Avoid using \"px\" as units; use \"dp\" instead", null); + } + } else if ("textSize".equals(attribute.getLocalName()) + && (value.endsWith("dp") || value.endsWith("dip")) //$NON-NLS-1$ //$NON-NLS-2$ + && (value.matches("\\d+di?p"))) { + if (context.isEnabled(DP_ISSUE)) { + context.report(DP_ISSUE, attribute, context.getLocation(attribute), + "Should use \"sp\" instead of \"dp\" for text sizes", null); + } } } } 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 5299ff7..15a0d65 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 @@ -276,8 +276,25 @@ public class SecurityDetector extends Detector implements Detector.XmlScanner, } } + private boolean isStandardReceiver(Element element) { + // Checks whether a broadcast receiver receives a standard Android action + for (Element child : LintUtils.getChildren(element)) { + if (child.getTagName().equals(TAG_INTENT_FILTER)) { + for (Element innerChild: LintUtils.getChildren(child)) { + if (innerChild.getTagName().equals("action")) { //$NON-NLS-1$ + String categoryString = innerChild.getAttributeNS(ANDROID_URI, ATTR_NAME); + return categoryString.startsWith("android.intent.action."); //$NON-NLS-1$ + } + } + } + } + + return false; + } + private void checkReceiver(XmlContext context, Element element) { - if (getExported(element) && isUnprotectedByPermission(element)) { + if (getExported(element) && isUnprotectedByPermission(element) && + !isStandardReceiver(element)) { // No declared permission for this exported receiver: complain context.report(EXPORTED_RECEIVER, element, context.getLocation(element), "Exported receiver does not require permission", null); 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 d091ce1..2a32af7 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 @@ -19,6 +19,7 @@ package com.android.tools.lint.checks; import static com.android.tools.lint.detector.api.LintConstants.ANDROID_URI; import static com.android.tools.lint.detector.api.LintConstants.ATTR_BACKGROUND; import static com.android.tools.lint.detector.api.LintConstants.ATTR_LAYOUT_WEIGHT; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_SCALE_TYPE; import static com.android.tools.lint.detector.api.LintConstants.IMAGE_VIEW; import static com.android.tools.lint.detector.api.LintConstants.LINEAR_LAYOUT; import static com.android.tools.lint.detector.api.LintConstants.TEXT_VIEW; @@ -94,6 +95,15 @@ public class UseCompoundDrawableDetector extends LayoutDetector { return; } + // Certain scale types cannot be done with compound drawables + String scaleType = first.getTagName().equals(IMAGE_VIEW) + ? first.getAttributeNS(ANDROID_URI, ATTR_SCALE_TYPE) + : second.getAttributeNS(ANDROID_URI, ATTR_SCALE_TYPE); + if (scaleType != null && !scaleType.isEmpty()) { + // For now, ignore if any scale type is set + return; + } + context.report(ISSUE, element, context.getLocation(element), "This tag and its children can be replaced by one <TextView/> and " + "a compound drawable", null); diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/PxUsageDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/PxUsageDetectorTest.java index db5afb4..04ed0a6 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/PxUsageDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/PxUsageDetectorTest.java @@ -25,9 +25,16 @@ public class PxUsageDetectorTest extends AbstractCheckTest { return new PxUsageDetector(); } - public void testProguard() throws Exception { + public void testPx() throws Exception { assertEquals( "now_playing_after.xml:41: Warning: Avoid using \"px\" as units; use \"dp\" instead", lintFiles("res/layout/now_playing_after.xml")); } + + public void testSp() throws Exception { + assertEquals( + "textsize.xml:11: Warning: Should use \"sp\" instead of \"dp\" for text sizes\n" + + "textsize.xml:16: Warning: Should use \"sp\" instead of \"dp\" for text sizes", + lintFiles("res/layout/textsize.xml")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/SecurityDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/SecurityDetectorTest.java index 0978826..8105ca7 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/SecurityDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/SecurityDetectorTest.java @@ -196,4 +196,13 @@ public class SecurityDetectorTest extends AbstractCheckTest { "exportreceiver4.xml=>AndroidManifest.xml", "res/values/strings.xml")); } + + public void testReceiver5() throws Exception { + // Intent filter for standard Android action + assertEquals( + "No warnings.", + lintProject( + "exportreceiver5.xml=>AndroidManifest.xml", + "res/values/strings.xml")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java index 6abfa71..6b29043 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java @@ -38,4 +38,11 @@ public class UseCompoundDrawableDetectorTest extends AbstractCheckTest { "No warnings.", lintFiles("res/layout/compound2.xml")); } + + public void testCompound3() throws Exception { + // Ignore layouts that set an image scale type + assertEquals( + "No warnings.", + lintFiles("res/layout/compound3.xml")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/exportreceiver5.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/exportreceiver5.xml new file mode 100644 index 0000000..afa74cf --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/exportreceiver5.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="foo.bar2" + android:versionCode="1" + android:versionName="1.0" > + + <uses-sdk android:minSdkVersion="14" /> + + <application + android:icon="@drawable/ic_launcher" + android:label="@string/app_name"> + <receiver> + <intent-filter> + <action android:name="android.intent.action.BOOT_COMPLETED" /> + </intent-filter> + </receiver> + </application> + +</manifest> + diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/compound3.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/compound3.xml new file mode 100644 index 0000000..68d42fa --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/compound3.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ImageView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:scaleType="fitStart" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + +</LinearLayout> diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/textsize.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/textsize.xml new file mode 100644 index 0000000..8a480ef --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/textsize.xml @@ -0,0 +1,28 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/LinearLayout1" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" > + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="14dp" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="14dip" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="14sp" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="@android/dimen/mysizedp" /> + +</LinearLayout> diff --git a/traceview/src/com/android/traceview/DmTraceReader.java b/traceview/src/com/android/traceview/DmTraceReader.java index b49d75e..9bd6882 100644 --- a/traceview/src/com/android/traceview/DmTraceReader.java +++ b/traceview/src/com/android/traceview/DmTraceReader.java @@ -668,7 +668,7 @@ public class DmTraceReader extends TraceReader { System.out.print("\nMethod Stats\n"); System.out.print("Excl Cpu Incl Cpu Excl Real Incl Real Calls Method\n"); for (MethodData md : mSortedMethods) { - System.out.format("%9d %9d %9s %s\n", + System.out.format("%9d %9d %9d %9d %9s %s\n", md.getElapsedExclusiveCpuTime(), md.getElapsedInclusiveCpuTime(), md.getElapsedExclusiveRealTime(), md.getElapsedInclusiveRealTime(), md.getCalls(), md.getProfileName()); |