Loading apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java 0 → 100644 +370 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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 android.widget; import static android.view.View.MeasureSpec.AT_MOST; import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.UNSPECIFIED; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Typeface; import android.graphics.Canvas; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; import android.support.test.InstrumentationRegistry; import android.support.test.filters.LargeTest; import android.support.test.runner.AndroidJUnit4; import android.text.PrecomputedText; import android.text.Layout; import android.text.BoringLayout; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextPaint; import android.text.style.TextAppearanceSpan; import android.view.LayoutInflater; import android.text.TextPerfUtils; import android.view.View.MeasureSpec; import android.view.DisplayListCanvas; import android.view.RenderNode; import com.android.perftests.core.R; import java.util.Random; import java.util.Locale; import org.junit.Before; import org.junit.Test; import org.junit.Rule; import org.junit.runner.RunWith; import static org.junit.Assert.assertTrue; import static android.widget.TextView.UNKNOWN_BORING; @LargeTest @RunWith(AndroidJUnit4.class) public class TextViewPrecomputedTextPerfTest { private static final int WORD_LENGTH = 9; // Random word has 9 characters. private static final int WORDS_IN_LINE = 8; // Roughly, 8 words in a line. private static final boolean NO_STYLE_TEXT = false; private static final boolean STYLE_TEXT = true; private static TextPaint PAINT = new TextPaint(); private static final int TEXT_WIDTH = WORDS_IN_LINE * WORD_LENGTH * (int) PAINT.getTextSize(); public TextViewPrecomputedTextPerfTest() {} private static class TestableTextView extends TextView { public TestableTextView(Context ctx) { super(ctx); } public void onMeasure(int w, int h) { super.onMeasure(w, h); } public void onDraw(Canvas canvas) { super.onDraw(canvas); } } @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); private TextPerfUtils mTextUtil = new TextPerfUtils(); @Before public void setUp() { mTextUtil.resetRandom(0 /* seed */); } private static Context getContext() { return InstrumentationRegistry.getTargetContext(); } @Test public void testNewLayout_RandomText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); final TextView textView = new TextView(getContext()); textView.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED); textView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL); textView.setText(text); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.makeNewLayout(TEXT_WIDTH, TEXT_WIDTH, UNKNOWN_BORING, UNKNOWN_BORING, TEXT_WIDTH, false); } } @Test public void testNewLayout_PrecomputedText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TextView textView = new TextView(getContext()); textView.setTextMetricsParams(params); textView.setText(text); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.makeNewLayout(TEXT_WIDTH, TEXT_WIDTH, UNKNOWN_BORING, UNKNOWN_BORING, TEXT_WIDTH, false); } } @Test public void testNewLayout_PrecomputedText_Selectable() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TextView textView = new TextView(getContext()); textView.setTextIsSelectable(true); textView.setTextMetricsParams(params); textView.setText(text); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.makeNewLayout(TEXT_WIDTH, TEXT_WIDTH, UNKNOWN_BORING, UNKNOWN_BORING, TEXT_WIDTH, false); } } @Test public void testSetText_RandomText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); final TextView textView = new TextView(getContext()); textView.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED); textView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.setText(text); } } @Test public void testSetText_PrecomputedText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TextView textView = new TextView(getContext()); textView.setTextMetricsParams(params); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.setText(text); } } @Test public void testSetText_PrecomputedText_Selectable() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TextView textView = new TextView(getContext()); textView.setTextIsSelectable(true); textView.setTextMetricsParams(params); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.setText(text); } } @Test public void testOnMeasure_RandomText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); while (state.keepRunning()) { state.pauseTiming(); final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); final TestableTextView textView = new TestableTextView(getContext()); textView.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED); textView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL); textView.setText(text); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onMeasure(width, height); } } @Test public void testOnMeasure_PrecomputedText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TestableTextView textView = new TestableTextView(getContext()); textView.setTextMetricsParams(params); textView.setText(text); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onMeasure(width, height); } } @Test public void testOnMeasure_PrecomputedText_Selectable() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TestableTextView textView = new TestableTextView(getContext()); textView.setTextIsSelectable(true); textView.setTextMetricsParams(params); textView.setText(text); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onMeasure(width, height); } } @Test public void testOnDraw_RandomText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); final RenderNode node = RenderNode.create("benchmark", null); while (state.keepRunning()) { state.pauseTiming(); final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); final TestableTextView textView = new TestableTextView(getContext()); textView.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED); textView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL); textView.setText(text); textView.nullLayouts(); textView.onMeasure(width, height); final DisplayListCanvas c = node.start( textView.getMeasuredWidth(), textView.getMeasuredHeight()); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onDraw(c); } } @Test public void testOnDraw_PrecomputedText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); final RenderNode node = RenderNode.create("benchmark", null); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TestableTextView textView = new TestableTextView(getContext()); textView.setTextMetricsParams(params); textView.setText(text); textView.nullLayouts(); textView.onMeasure(width, height); final DisplayListCanvas c = node.start( textView.getMeasuredWidth(), textView.getMeasuredHeight()); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onDraw(c); } } @Test public void testOnDraw_PrecomputedText_Selectable() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); final RenderNode node = RenderNode.create("benchmark", null); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TestableTextView textView = new TestableTextView(getContext()); textView.setTextIsSelectable(true); textView.setTextMetricsParams(params); textView.setText(text); textView.nullLayouts(); textView.onMeasure(width, height); final DisplayListCanvas c = node.start( textView.getMeasuredWidth(), textView.getMeasuredHeight()); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onDraw(c); } } } core/java/android/widget/TextView.java +8 −3 Original line number Diff line number Diff line Loading @@ -8084,7 +8084,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return false; } private void nullLayouts() { /** @hide */ @VisibleForTesting public void nullLayouts() { if (mLayout instanceof BoringLayout && mSavedLayout == null) { mSavedLayout = (BoringLayout) mLayout; } Loading Loading @@ -8178,7 +8180,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * not the full view width with padding. * {@hide} */ protected void makeNewLayout(int wantWidth, int hintWidth, @VisibleForTesting public void makeNewLayout(int wantWidth, int hintWidth, BoringLayout.Metrics boring, BoringLayout.Metrics hintBoring, int ellipsisWidth, boolean bringIntoView) { Loading Loading @@ -8468,7 +8471,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return mIncludePad; } private static final BoringLayout.Metrics UNKNOWN_BORING = new BoringLayout.Metrics(); /** @hide */ @VisibleForTesting public static final BoringLayout.Metrics UNKNOWN_BORING = new BoringLayout.Metrics(); @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Loading core/tests/coretests/src/android/widget/layout/linear/ExceptionTextView.java +4 −8 Original line number Diff line number Diff line Loading @@ -16,12 +16,10 @@ package android.widget.layout.linear; import junit.framework.Assert; import android.widget.EditText; import android.content.Context; import android.util.AttributeSet; import android.text.BoringLayout; import android.util.AttributeSet; import android.widget.EditText; /** Loading Loading @@ -50,10 +48,8 @@ public class ExceptionTextView extends EditText { } @Override protected void makeNewLayout(int w, int hintWidth, BoringLayout.Metrics boring, BoringLayout.Metrics hintMetrics, int ellipsizedWidth, boolean bringIntoView) { public void makeNewLayout(int w, int hintWidth, BoringLayout.Metrics boring, BoringLayout.Metrics hintMetrics, int ellipsizedWidth, boolean bringIntoView) { if (w < 0) { mFailed = true; w = 100; Loading Loading
apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java 0 → 100644 +370 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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 android.widget; import static android.view.View.MeasureSpec.AT_MOST; import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.UNSPECIFIED; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Typeface; import android.graphics.Canvas; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; import android.support.test.InstrumentationRegistry; import android.support.test.filters.LargeTest; import android.support.test.runner.AndroidJUnit4; import android.text.PrecomputedText; import android.text.Layout; import android.text.BoringLayout; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextPaint; import android.text.style.TextAppearanceSpan; import android.view.LayoutInflater; import android.text.TextPerfUtils; import android.view.View.MeasureSpec; import android.view.DisplayListCanvas; import android.view.RenderNode; import com.android.perftests.core.R; import java.util.Random; import java.util.Locale; import org.junit.Before; import org.junit.Test; import org.junit.Rule; import org.junit.runner.RunWith; import static org.junit.Assert.assertTrue; import static android.widget.TextView.UNKNOWN_BORING; @LargeTest @RunWith(AndroidJUnit4.class) public class TextViewPrecomputedTextPerfTest { private static final int WORD_LENGTH = 9; // Random word has 9 characters. private static final int WORDS_IN_LINE = 8; // Roughly, 8 words in a line. private static final boolean NO_STYLE_TEXT = false; private static final boolean STYLE_TEXT = true; private static TextPaint PAINT = new TextPaint(); private static final int TEXT_WIDTH = WORDS_IN_LINE * WORD_LENGTH * (int) PAINT.getTextSize(); public TextViewPrecomputedTextPerfTest() {} private static class TestableTextView extends TextView { public TestableTextView(Context ctx) { super(ctx); } public void onMeasure(int w, int h) { super.onMeasure(w, h); } public void onDraw(Canvas canvas) { super.onDraw(canvas); } } @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); private TextPerfUtils mTextUtil = new TextPerfUtils(); @Before public void setUp() { mTextUtil.resetRandom(0 /* seed */); } private static Context getContext() { return InstrumentationRegistry.getTargetContext(); } @Test public void testNewLayout_RandomText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); final TextView textView = new TextView(getContext()); textView.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED); textView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL); textView.setText(text); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.makeNewLayout(TEXT_WIDTH, TEXT_WIDTH, UNKNOWN_BORING, UNKNOWN_BORING, TEXT_WIDTH, false); } } @Test public void testNewLayout_PrecomputedText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TextView textView = new TextView(getContext()); textView.setTextMetricsParams(params); textView.setText(text); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.makeNewLayout(TEXT_WIDTH, TEXT_WIDTH, UNKNOWN_BORING, UNKNOWN_BORING, TEXT_WIDTH, false); } } @Test public void testNewLayout_PrecomputedText_Selectable() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TextView textView = new TextView(getContext()); textView.setTextIsSelectable(true); textView.setTextMetricsParams(params); textView.setText(text); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.makeNewLayout(TEXT_WIDTH, TEXT_WIDTH, UNKNOWN_BORING, UNKNOWN_BORING, TEXT_WIDTH, false); } } @Test public void testSetText_RandomText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); final TextView textView = new TextView(getContext()); textView.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED); textView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.setText(text); } } @Test public void testSetText_PrecomputedText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TextView textView = new TextView(getContext()); textView.setTextMetricsParams(params); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.setText(text); } } @Test public void testSetText_PrecomputedText_Selectable() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BoringLayout.Metrics metrics = new BoringLayout.Metrics(); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TextView textView = new TextView(getContext()); textView.setTextIsSelectable(true); textView.setTextMetricsParams(params); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.setText(text); } } @Test public void testOnMeasure_RandomText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); while (state.keepRunning()) { state.pauseTiming(); final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); final TestableTextView textView = new TestableTextView(getContext()); textView.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED); textView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL); textView.setText(text); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onMeasure(width, height); } } @Test public void testOnMeasure_PrecomputedText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TestableTextView textView = new TestableTextView(getContext()); textView.setTextMetricsParams(params); textView.setText(text); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onMeasure(width, height); } } @Test public void testOnMeasure_PrecomputedText_Selectable() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TestableTextView textView = new TestableTextView(getContext()); textView.setTextIsSelectable(true); textView.setTextMetricsParams(params); textView.setText(text); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onMeasure(width, height); } } @Test public void testOnDraw_RandomText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); final RenderNode node = RenderNode.create("benchmark", null); while (state.keepRunning()) { state.pauseTiming(); final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); final TestableTextView textView = new TestableTextView(getContext()); textView.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED); textView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL); textView.setText(text); textView.nullLayouts(); textView.onMeasure(width, height); final DisplayListCanvas c = node.start( textView.getMeasuredWidth(), textView.getMeasuredHeight()); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onDraw(c); } } @Test public void testOnDraw_PrecomputedText() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); final RenderNode node = RenderNode.create("benchmark", null); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TestableTextView textView = new TestableTextView(getContext()); textView.setTextMetricsParams(params); textView.setText(text); textView.nullLayouts(); textView.onMeasure(width, height); final DisplayListCanvas c = node.start( textView.getMeasuredWidth(), textView.getMeasuredHeight()); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onDraw(c); } } @Test public void testOnDraw_PrecomputedText_Selectable() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int width = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, TEXT_WIDTH); int height = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0); final RenderNode node = RenderNode.create("benchmark", null); while (state.keepRunning()) { state.pauseTiming(); final PrecomputedText.Params params = new PrecomputedText.Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED).build(); final CharSequence text = PrecomputedText.create( mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), params); final TestableTextView textView = new TestableTextView(getContext()); textView.setTextIsSelectable(true); textView.setTextMetricsParams(params); textView.setText(text); textView.nullLayouts(); textView.onMeasure(width, height); final DisplayListCanvas c = node.start( textView.getMeasuredWidth(), textView.getMeasuredHeight()); textView.nullLayouts(); Canvas.freeTextLayoutCaches(); state.resumeTiming(); textView.onDraw(c); } } }
core/java/android/widget/TextView.java +8 −3 Original line number Diff line number Diff line Loading @@ -8084,7 +8084,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return false; } private void nullLayouts() { /** @hide */ @VisibleForTesting public void nullLayouts() { if (mLayout instanceof BoringLayout && mSavedLayout == null) { mSavedLayout = (BoringLayout) mLayout; } Loading Loading @@ -8178,7 +8180,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * not the full view width with padding. * {@hide} */ protected void makeNewLayout(int wantWidth, int hintWidth, @VisibleForTesting public void makeNewLayout(int wantWidth, int hintWidth, BoringLayout.Metrics boring, BoringLayout.Metrics hintBoring, int ellipsisWidth, boolean bringIntoView) { Loading Loading @@ -8468,7 +8471,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return mIncludePad; } private static final BoringLayout.Metrics UNKNOWN_BORING = new BoringLayout.Metrics(); /** @hide */ @VisibleForTesting public static final BoringLayout.Metrics UNKNOWN_BORING = new BoringLayout.Metrics(); @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Loading
core/tests/coretests/src/android/widget/layout/linear/ExceptionTextView.java +4 −8 Original line number Diff line number Diff line Loading @@ -16,12 +16,10 @@ package android.widget.layout.linear; import junit.framework.Assert; import android.widget.EditText; import android.content.Context; import android.util.AttributeSet; import android.text.BoringLayout; import android.util.AttributeSet; import android.widget.EditText; /** Loading Loading @@ -50,10 +48,8 @@ public class ExceptionTextView extends EditText { } @Override protected void makeNewLayout(int w, int hintWidth, BoringLayout.Metrics boring, BoringLayout.Metrics hintMetrics, int ellipsizedWidth, boolean bringIntoView) { public void makeNewLayout(int w, int hintWidth, BoringLayout.Metrics boring, BoringLayout.Metrics hintMetrics, int ellipsizedWidth, boolean bringIntoView) { if (w < 0) { mFailed = true; w = 100; Loading