diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-07-05 07:23:54 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-07-05 07:23:54 +0000 |
commit | 80ed4728ea443a560baf7677367500d618a98f27 (patch) | |
tree | 29ffbb68785b38ea42bfb91da61d845c14f10b82 | |
parent | 8c18c45e978ef270fba5424534611710b4386f6a (diff) | |
parent | b2dfcdc4a71e44089871a0520109a55abbe16615 (diff) | |
download | layoutlib-80ed4728ea443a560baf7677367500d618a98f27.tar.gz |
release-request-96c1d2fa-6213-4670-8f45-7a1668ab4a26-for-git_oc-mr1-release-4153896 snap-temp-L86500000079599461
Change-Id: I3bfc0704cf490250dc582a76cc16e90f15b2d10c
-rw-r--r-- | bridge/src/android/graphics/BidiRenderer.java | 85 | ||||
-rw-r--r-- | bridge/src/android/graphics/NinePatch_Delegate.java | 13 | ||||
-rw-r--r-- | bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java | 52 | ||||
-rw-r--r-- | bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java | 8 | ||||
-rw-r--r-- | bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java | 120 | ||||
-rw-r--r-- | bridge/tests/res/testApp/MyApplication/golden/activity.png | bin | 36035 -> 35669 bytes | |||
-rw-r--r-- | bridge/tests/res/testApp/MyApplication/golden/allwidgets.png | bin | 67362 -> 66711 bytes | |||
-rw-r--r-- | bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png | bin | 52448 -> 51410 bytes | |||
-rw-r--r-- | bridge/tests/res/testApp/MyApplication/golden/font_test.png | bin | 52171 -> 52715 bytes | |||
-rw-r--r-- | bridge/tests/src/com/android/layoutlib/bridge/impl/ResourceHelperTest.java | 51 | ||||
-rw-r--r-- | bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java | 3 |
11 files changed, 211 insertions, 121 deletions
diff --git a/bridge/src/android/graphics/BidiRenderer.java b/bridge/src/android/graphics/BidiRenderer.java index f2904b2446..63691c3889 100644 --- a/bridge/src/android/graphics/BidiRenderer.java +++ b/bridge/src/android/graphics/BidiRenderer.java @@ -19,8 +19,9 @@ package android.graphics; import com.android.ide.common.rendering.api.LayoutLog; import com.android.layoutlib.bridge.Bridge; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.graphics.Paint_Delegate.FontInfo; -import android.icu.lang.UScript; import android.icu.lang.UScriptRun; import android.icu.text.Bidi; import android.icu.text.BidiRun; @@ -32,7 +33,6 @@ import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -45,26 +45,20 @@ public class BidiRenderer { private static String JAVA_VENDOR = System.getProperty("java.vendor"); private static class ScriptRun { - int start; - int limit; - boolean isRtl; - int scriptCode; - Font font; + private final int start; + private final int limit; + private final Font font; - public ScriptRun(int start, int limit, boolean isRtl) { + private ScriptRun(int start, int limit, @NonNull Font font) { this.start = start; this.limit = limit; - this.isRtl = isRtl; - this.scriptCode = UScript.INVALID_CODE; + this.font = font; } } private final Graphics2D mGraphics; private final Paint_Delegate mPaint; private char[] mText; - // This List can contain nulls. A null font implies that the we weren't able to load the font - // properly. So, if we encounter a situation where we try to use that font, log a warning. - private List<Font> mFonts; // Bounds of the text drawn so far. private RectF mBounds; private float mBaseline; @@ -79,14 +73,6 @@ public class BidiRenderer { mGraphics = graphics; mPaint = paint; mText = text; - mFonts = new ArrayList<Font>(paint.getFonts().size()); - for (FontInfo fontInfo : paint.getFonts()) { - if (fontInfo == null) { - mFonts.add(null); - continue; - } - mFonts.add(fontInfo.mFont); - } mBounds = new RectF(); } @@ -98,7 +84,7 @@ public class BidiRenderer { * */ public BidiRenderer setRenderLocation(float x, float y) { - mBounds = new RectF(x, y, x, y); + mBounds.set(x, y, x, y); mBaseline = y; return this; } @@ -141,7 +127,7 @@ public class BidiRenderer { int advancesIndex, boolean draw) { // We break the text into scripts and then select font based on it and then render each of // the script runs. - for (ScriptRun run : getScriptRuns(mText, start, limit, isRtl, mFonts)) { + for (ScriptRun run : getScriptRuns(mText, start, limit, mPaint.getFonts())) { int flag = Font.LAYOUT_NO_LIMIT_CONTEXT | Font.LAYOUT_NO_START_CONTEXT; flag |= isRtl ? Font.LAYOUT_RIGHT_TO_LEFT : Font.LAYOUT_LEFT_TO_RIGHT; renderScript(run.start, run.limit, run.font, flag, advances, advancesIndex, draw); @@ -157,7 +143,7 @@ public class BidiRenderer { */ private void renderScript(int start, int limit, Font preferredFont, int flag, float[] advances, int advancesIndex, boolean draw) { - if (mFonts.size() == 0 || preferredFont == null) { + if (mPaint.getFonts().size() == 0 || preferredFont == null) { return; } @@ -179,7 +165,10 @@ public class BidiRenderer { // The current character cannot be drawn with the preferred font. Cycle through all the // fonts to check which one can draw it. int charCount = Character.isHighSurrogate(mText[start]) ? 2 : 1; - for (Font font : mFonts) { + List<FontInfo> fontInfos = mPaint.getFonts(); + //noinspection ForLoopReplaceableByForEach (avoid iterator allocation) + for (int i = 0; i < fontInfos.size(); i++) { + Font font = fontInfos.get(i).mFont; if (font == null) { logFontWarning(); continue; @@ -250,60 +239,62 @@ public class BidiRenderer { // Update the bounds. Rectangle2D awtBounds = gv.getLogicalBounds(); - RectF bounds = awtRectToAndroidRect(awtBounds, mBounds.right, mBaseline); // If the width of the bounds is zero, no text had been drawn earlier. Hence, use the // coordinates from the bounds as an offset. if (Math.abs(mBounds.right - mBounds.left) == 0) { - mBounds = bounds; + mBounds = awtRectToAndroidRect(awtBounds, mBounds.right, mBaseline, mBounds); } else { - mBounds.union(bounds); + mBounds.union(awtRectToAndroidRect(awtBounds, mBounds.right, mBaseline, null)); } } // --- Static helper methods --- - private static RectF awtRectToAndroidRect(Rectangle2D awtRec, float offsetX, float offsetY) { + private static RectF awtRectToAndroidRect(Rectangle2D awtRec, float offsetX, float offsetY, + @Nullable RectF destination) { float left = (float) awtRec.getX(); float top = (float) awtRec.getY(); float right = (float) (left + awtRec.getWidth()); float bottom = (float) (top + awtRec.getHeight()); - RectF androidRect = new RectF(left, top, right, bottom); - androidRect.offset(offsetX, offsetY); - return androidRect; + if (destination != null) { + destination.set(left, top, right, bottom); + } else { + destination = new RectF(left, top, right, bottom); + } + destination.offset(offsetX, offsetY); + return destination; } - /* package */ static List<ScriptRun> getScriptRuns(char[] text, int start, int limit, - boolean isRtl, List<Font> fonts) { - LinkedList<ScriptRun> scriptRuns = new LinkedList<ScriptRun>(); + private static List<ScriptRun> getScriptRuns(char[] text, int start, int limit, List<FontInfo> fonts) { + LinkedList<ScriptRun> scriptRuns = new LinkedList<>(); int count = limit - start; UScriptRun uScriptRun = new UScriptRun(text, start, count); while (uScriptRun.next()) { int scriptStart = uScriptRun.getScriptStart(); int scriptLimit = uScriptRun.getScriptLimit(); - ScriptRun run = new ScriptRun(scriptStart, scriptLimit, isRtl); - run.scriptCode = uScriptRun.getScriptCode(); - setScriptFont(text, run, fonts); + ScriptRun run = new ScriptRun( + scriptStart, scriptLimit, + getScriptFont(text, scriptStart, scriptLimit, fonts)); scriptRuns.add(run); } - return scriptRuns; } // TODO: Replace this method with one which returns the font based on the scriptCode. - private static void setScriptFont(char[] text, ScriptRun run, - List<Font> fonts) { - for (Font font : fonts) { - if (font == null) { + @NonNull + private static Font getScriptFont(char[] text, int start, int limit, List<FontInfo> fonts) { + for (FontInfo fontInfo : fonts) { + if (fontInfo.mFont == null) { logFontWarning(); continue; } - if (font.canDisplayUpTo(text, run.start, run.limit) == -1) { - run.font = font; - return; + if (fontInfo.mFont.canDisplayUpTo(text, start, limit) == -1) { + return fontInfo.mFont; } } - run.font = fonts.get(0); + + return fonts.get(0).mFont; } private static int getIcuFlags(int bidiFlag) { diff --git a/bridge/src/android/graphics/NinePatch_Delegate.java b/bridge/src/android/graphics/NinePatch_Delegate.java index 1f0eb3bab5..43e5b0f974 100644 --- a/bridge/src/android/graphics/NinePatch_Delegate.java +++ b/bridge/src/android/graphics/NinePatch_Delegate.java @@ -19,14 +19,11 @@ package android.graphics; import com.android.ide.common.rendering.api.LayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; -import com.android.layoutlib.bridge.impl.GcSnapshot; import com.android.ninepatch.NinePatchChunk; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import android.graphics.drawable.NinePatchDrawable; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -50,7 +47,7 @@ public final class NinePatch_Delegate { // ---- delegate manager ---- private static final DelegateManager<NinePatch_Delegate> sManager = - new DelegateManager<NinePatch_Delegate>(NinePatch_Delegate.class); + new DelegateManager<>(NinePatch_Delegate.class); // ---- delegate helper data ---- /** @@ -62,8 +59,7 @@ public final class NinePatch_Delegate { * Using the cache map allows us to not have to deserialize the byte[] back into a * {@link NinePatchChunk} every time a rendering is done. */ - private final static Map<byte[], SoftReference<NinePatchChunk>> sChunkCache = - new HashMap<byte[], SoftReference<NinePatchChunk>>(); + private final static Map<byte[], SoftReference<NinePatchChunk>> sChunkCache = new HashMap<>(); // ---- delegate data ---- private byte[] chunk; @@ -97,7 +93,7 @@ public final class NinePatch_Delegate { // get the array and add it to the cache byte[] array = baos.toByteArray(); - sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk)); + sChunkCache.put(array, new SoftReference<>(chunk)); return array; } @@ -122,7 +118,7 @@ public final class NinePatch_Delegate { // put back the chunk in the cache if (chunk != null) { - sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk)); + sChunkCache.put(array, new SoftReference<>(chunk)); } } catch (IOException e) { Bridge.getLog().error(LayoutLog.TAG_BROKEN, @@ -151,7 +147,6 @@ public final class NinePatch_Delegate { /*package*/ static boolean isNinePatchChunk(byte[] chunk) { NinePatchChunk chunkObject = getChunk(chunk); return chunkObject != null; - } @LayoutlibDelegate diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java new file mode 100644 index 0000000000..730ac1300e --- /dev/null +++ b/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2017 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.layoutlib.bridge.android.support; + +import com.android.ide.common.rendering.api.LayoutLog; +import com.android.layoutlib.bridge.Bridge; +import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException; + +import android.content.Context; +import android.widget.TabHost; + +import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause; +import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod; +import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke; + +/** + * Utility class for working with android.support.v4.app.FragmentTabHost + */ +public class FragmentTabHostUtil { + + public static final String CN_FRAGMENT_TAB_HOST = "android.support.v4.app.FragmentTabHost"; + + /** + * Calls the setup method for the FragmentTabHost tabHost + */ + public static void setup(TabHost tabHost, Context context) { + try { + invoke(getMethod(tabHost.getClass(), "setup", Context.class, + Class.forName("android.support.v4.app.FragmentManager", true, + tabHost.getClass().getClassLoader()), int.class), tabHost, context, null, + android.R.id.tabcontent); + } catch (ReflectionException | ClassNotFoundException e) { + Throwable cause = getCause(e); + Bridge.getLog().error(LayoutLog.TAG_BROKEN, + "Error occurred while trying to setup FragmentTabHost.", cause, null); + } + } +} diff --git a/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java index a1d614da2a..5adba23b2a 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java @@ -41,9 +41,11 @@ import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; import com.android.layoutlib.bridge.android.RenderParamsFlags; import com.android.layoutlib.bridge.android.graphics.NopCanvas; import com.android.layoutlib.bridge.android.support.DesignLibUtil; +import com.android.layoutlib.bridge.android.support.FragmentTabHostUtil; import com.android.layoutlib.bridge.android.support.SupportPreferencesUtil; import com.android.layoutlib.bridge.impl.binding.FakeAdapter; import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; +import com.android.layoutlib.bridge.util.ReflectionUtils; import com.android.resources.ResourceType; import com.android.tools.layoutlib.java.System_Delegate; import com.android.util.Pair; @@ -828,7 +830,11 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { // this must be called before addTab() so that the TabHost searches its TabWidget // and FrameLayout. - tabHost.setup(); + if (ReflectionUtils.isInstanceOf(tabHost, FragmentTabHostUtil.CN_FRAGMENT_TAB_HOST)) { + FragmentTabHostUtil.setup(tabHost, getContext()); + } else { + tabHost.setup(); + } if (count == 0) { // Create a dummy child to get a single tab diff --git a/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java index 2826050628..e33a2941c8 100644 --- a/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java +++ b/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java @@ -80,55 +80,57 @@ public final class ResourceHelper { * @return the color as an int * @throws NumberFormatException if the conversion failed. */ - public static int getColor(String value) { - if (value != null) { - value = value.trim(); - if (!value.startsWith("#")) { - if (value.startsWith(SdkConstants.PREFIX_THEME_REF)) { - throw new NumberFormatException(String.format( - "Attribute '%s' not found. Are you using the right theme?", value)); - } - throw new NumberFormatException( - String.format("Color value '%s' must start with #", value)); - } + public static int getColor(@Nullable String value) { + if (value == null) { + throw new NumberFormatException("null value"); + } + + value = value.trim(); + int len = value.length(); - value = value.substring(1); + // make sure it's not longer than 32bit or smaller than the RGB format + if (len < 2 || len > 9) { + throw new NumberFormatException(String.format( + "Color value '%s' has wrong size. Format is either" + + "#AARRGGBB, #RRGGBB, #RGB, or #ARGB", + value)); + } - // make sure it's not longer than 32bit - if (value.length() > 8) { + if (value.charAt(0) != '#') { + if (value.startsWith(SdkConstants.PREFIX_THEME_REF)) { throw new NumberFormatException(String.format( - "Color value '%s' is too long. Format is either" + - "#AARRGGBB, #RRGGBB, #RGB, or #ARGB", - value)); - } - - if (value.length() == 3) { // RGB format - char[] color = new char[8]; - color[0] = color[1] = 'F'; - color[2] = color[3] = value.charAt(0); - color[4] = color[5] = value.charAt(1); - color[6] = color[7] = value.charAt(2); - value = new String(color); - } else if (value.length() == 4) { // ARGB format - char[] color = new char[8]; - color[0] = color[1] = value.charAt(0); - color[2] = color[3] = value.charAt(1); - color[4] = color[5] = value.charAt(2); - color[6] = color[7] = value.charAt(3); - value = new String(color); - } else if (value.length() == 6) { - value = "FF" + value; + "Attribute '%s' not found. Are you using the right theme?", value)); } + throw new NumberFormatException( + String.format("Color value '%s' must start with #", value)); + } - // this is a RRGGBB or AARRGGBB value - - // Integer.parseInt will fail to parse strings like "ff191919", so we use - // a Long, but cast the result back into an int, since we know that we're only - // dealing with 32 bit values. - return (int)Long.parseLong(value, 16); + value = value.substring(1); + + if (len == 4) { // RGB format + char[] color = new char[8]; + color[0] = color[1] = 'F'; + color[2] = color[3] = value.charAt(0); + color[4] = color[5] = value.charAt(1); + color[6] = color[7] = value.charAt(2); + value = new String(color); + } else if (len == 5) { // ARGB format + char[] color = new char[8]; + color[0] = color[1] = value.charAt(0); + color[2] = color[3] = value.charAt(1); + color[4] = color[5] = value.charAt(2); + color[6] = color[7] = value.charAt(3); + value = new String(color); + } else if (len == 7) { + value = "FF" + value; } - throw new NumberFormatException(); + // this is a RRGGBB or AARRGGBB value + + // Integer.parseInt will fail to parse strings like "ff191919", so we use + // a Long, but cast the result back into an int, since we know that we're only + // dealing with 32 bit values. + return (int)Long.parseLong(value, 16); } /** @@ -149,6 +151,13 @@ public final class ResourceHelper { return null; } + // try to load the color state list from an int + try { + int color = getColor(value); + return ColorStateList.valueOf(color); + } catch (NumberFormatException ignored) { + } + XmlPullParser parser = null; // first check if the value is a file (xml most likely) Boolean psiParserSupport = context.getLayoutlibCallback().getFlag( @@ -216,16 +225,6 @@ public final class ResourceHelper { return null; } - } else { - // try to load the color state list from an int - try { - int color = getColor(value); - return ColorStateList.valueOf(color); - } catch (NumberFormatException e) { - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, - "Failed to convert " + value + " into a ColorStateList", e, - null /*data*/); - } } return null; @@ -316,6 +315,12 @@ public final class ResourceHelper { } String lowerCaseValue = stringValue.toLowerCase(); + // try the simple case first. Attempt to get a color from the value + try { + int color = getColor(stringValue); + return new ColorDrawable(color); + } catch (NumberFormatException ignore) { + } Density density = Density.MEDIUM; if (value instanceof DensityBasedResourceValue) { @@ -375,17 +380,6 @@ public final class ResourceHelper { Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ, "Failed lot load " + bmpFile.getAbsolutePath(), e, null /*data*/); } - } else { - // attempt to get a color from the value - try { - int color = getColor(stringValue); - return new ColorDrawable(color); - } catch (NumberFormatException e) { - // we'll return null below. - Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, - "Failed to convert " + stringValue + " into a drawable", e, - null /*data*/); - } } } diff --git a/bridge/tests/res/testApp/MyApplication/golden/activity.png b/bridge/tests/res/testApp/MyApplication/golden/activity.png Binary files differindex 773c5bee5d..650751eaf1 100644 --- a/bridge/tests/res/testApp/MyApplication/golden/activity.png +++ b/bridge/tests/res/testApp/MyApplication/golden/activity.png diff --git a/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png Binary files differindex 4391f47bd3..1ac8e1bca1 100644 --- a/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png +++ b/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png diff --git a/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png b/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png Binary files differindex bca334703b..0328fd127b 100644 --- a/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png +++ b/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png diff --git a/bridge/tests/res/testApp/MyApplication/golden/font_test.png b/bridge/tests/res/testApp/MyApplication/golden/font_test.png Binary files differindex 7e0c29afd4..3966ccbf02 100644 --- a/bridge/tests/res/testApp/MyApplication/golden/font_test.png +++ b/bridge/tests/res/testApp/MyApplication/golden/font_test.png diff --git a/bridge/tests/src/com/android/layoutlib/bridge/impl/ResourceHelperTest.java b/bridge/tests/src/com/android/layoutlib/bridge/impl/ResourceHelperTest.java new file mode 100644 index 0000000000..4e18f076a0 --- /dev/null +++ b/bridge/tests/src/com/android/layoutlib/bridge/impl/ResourceHelperTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017 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.layoutlib.bridge.impl; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ResourceHelperTest { + private static void assertNumberFormatException(Runnable runnable) { + try { + runnable.run(); + fail("NumberFormatException expected"); + } catch (NumberFormatException ignored) { + } + } + + @Test + public void testGetColor() { + assertNumberFormatException(() -> ResourceHelper.getColor("")); + assertNumberFormatException(() -> ResourceHelper.getColor("AFAFAF")); + assertNumberFormatException(() -> ResourceHelper.getColor("AAA")); + assertNumberFormatException(() -> ResourceHelper.getColor("#JFAFAF")); + assertNumberFormatException(() -> ResourceHelper.getColor("#AABBCCDDEE")); + assertNumberFormatException(() -> ResourceHelper.getColor("#JAAA")); + assertNumberFormatException(() -> ResourceHelper.getColor("#AA BBCC")); + + assertEquals(0xffaaaaaa, ResourceHelper.getColor("#AAA")); + assertEquals(0xffaaaaaa, ResourceHelper.getColor(" #AAA")); + assertEquals(0xffaaaaaa, ResourceHelper.getColor("#AAA ")); + assertEquals(0xffaaaaaa, ResourceHelper.getColor(" #AAA ")); + assertEquals(0xaaaaaa, ResourceHelper.getColor("#0AAA")); + assertEquals(0xffaabbcc, ResourceHelper.getColor("#AABBCC")); + assertEquals(0x12aabbcc, ResourceHelper.getColor("#12AABBCC")); + assertEquals(0x12345, ResourceHelper.getColor("#12345")); + } +}
\ No newline at end of file diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java index eb264d655a..e98c78971b 100644 --- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java +++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java @@ -20,6 +20,7 @@ import com.android.layoutlib.bridge.BridgeRenderSessionTest; import com.android.layoutlib.bridge.TestDelegates; import com.android.layoutlib.bridge.android.BridgeXmlBlockParserTest; import com.android.layoutlib.bridge.impl.LayoutParserWrapperTest; +import com.android.layoutlib.bridge.impl.ResourceHelperTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -36,7 +37,7 @@ import android.util.BridgeXmlPullAttributesTest; RenderTests.class, LayoutParserWrapperTest.class, BridgeXmlBlockParserTest.class, BridgeXmlPullAttributesTest.class, Matrix_DelegateTest.class, TestDelegates.class, PerformanceTests.class, - BridgeRenderSessionTest.class + BridgeRenderSessionTest.class, ResourceHelperTest.class }) public class Main { } |