Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package android.text;
     18 
     19 import android.app.Activity;
     20 import android.graphics.Canvas;
     21 import android.graphics.Paint;
     22 import android.graphics.Paint.FontMetricsInt;
     23 import android.os.Bundle;
     24 import android.perftests.utils.BenchmarkState;
     25 import android.perftests.utils.PerfStatusReporter;
     26 import android.perftests.utils.StubActivity;
     27 
     28 import android.support.test.InstrumentationRegistry;
     29 import android.support.test.filters.LargeTest;
     30 import android.support.test.rule.ActivityTestRule;
     31 import android.support.test.runner.AndroidJUnit4;
     32 import android.text.style.ReplacementSpan;
     33 import android.util.ArraySet;
     34 
     35 import static android.text.Layout.Alignment.ALIGN_NORMAL;
     36 
     37 import java.util.Arrays;
     38 import java.util.Collection;
     39 import java.util.Locale;
     40 import java.util.Random;
     41 
     42 import org.junit.Assert;
     43 import org.junit.Rule;
     44 import org.junit.Test;
     45 import org.junit.runner.RunWith;
     46 import org.junit.runners.Parameterized.Parameters;
     47 import org.junit.runners.Parameterized;
     48 
     49 @LargeTest
     50 @RunWith(Parameterized.class)
     51 public class DynamicLayoutPerfTest {
     52 
     53     @Parameters(name = "{0}")
     54     public static Collection cases() {
     55         return Arrays.asList(new Object[][] {
     56             { "0%", 0.0f},
     57             { "1%", 0.01f},
     58             { "5%", 0.05f},
     59             { "30%", 0.3f},
     60             { "100%", 1.0f},
     61         });
     62     }
     63 
     64     private final String mMetricKey;
     65     private final float mProbability;
     66     public DynamicLayoutPerfTest(String metricKey, float probability) {
     67         mMetricKey = metricKey;
     68         mProbability = probability;
     69     }
     70 
     71     private static class MockReplacementSpan extends ReplacementSpan {
     72         @Override
     73         public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
     74             return 10;
     75         }
     76 
     77         @Override
     78         public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top,
     79                 int y, int bottom, Paint paint) {
     80         }
     81     }
     82 
     83     @Rule
     84     public ActivityTestRule<StubActivity> mActivityRule = new ActivityTestRule(StubActivity.class);
     85 
     86     @Rule
     87     public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
     88 
     89 
     90     private final static String ALPHABETS = "abcdefghijklmnopqrstuvwxyz";
     91 
     92     private SpannableStringBuilder getText() {
     93         final long seed = 1234567890;
     94         final Random r = new Random(seed);
     95         final SpannableStringBuilder builder = new SpannableStringBuilder();
     96 
     97         final int paragraphCount = 100;
     98         for (int i = 0; i < paragraphCount; i++) {
     99             final int wordCount = 5 + r.nextInt(20);
    100             final boolean containsReplacementSpan = r.nextFloat() < mProbability;
    101             final int replacedWordIndex = containsReplacementSpan ? r.nextInt(wordCount) : -1;
    102             for (int j = 0; j < wordCount; j++) {
    103                 final int startIndex = builder.length();
    104                 final int wordLength = 1 + r.nextInt(10);
    105                 for (int k = 0; k < wordLength; k++) {
    106                     char c = ALPHABETS.charAt(r.nextInt(ALPHABETS.length()));
    107                     builder.append(c);
    108                 }
    109                 if (replacedWordIndex == j) {
    110                     builder.setSpan(new MockReplacementSpan(), startIndex,
    111                             builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    112                 }
    113                 builder.append(' ');
    114             }
    115             builder.append('\n');
    116         }
    117         return builder;
    118     }
    119 
    120     @Test
    121     public void testGetBlocksAlwaysNeedToBeRedrawn() {
    122         final SpannableStringBuilder text = getText();
    123         final DynamicLayout layout = new DynamicLayout(text, new TextPaint(), 1000,
    124                 ALIGN_NORMAL, 0, 0, false);
    125 
    126         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    127         final int steps = 10;
    128         while (state.keepRunning()) {
    129             for (int i = 0; i < steps; i++) {
    130                 int offset = (text.length() * i) / steps;
    131                 text.insert(offset, "\n");
    132                 text.delete(offset, offset + 1);
    133                 final ArraySet<Integer> set = layout.getBlocksAlwaysNeedToBeRedrawn();
    134                 if (set != null) {
    135                     for (int j = 0; j < set.size(); j++) {
    136                         layout.getBlockIndex(set.valueAt(j));
    137                     }
    138                 }
    139             }
    140         }
    141     }
    142 }
    143