• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.widget;
18 
19 import android.perftests.utils.BenchmarkState;
20 import android.perftests.utils.PerfStatusReporter;
21 import android.perftests.utils.PerfTestActivity;
22 import android.text.Selection;
23 import android.view.KeyEvent;
24 import android.view.View.MeasureSpec;
25 import android.view.ViewGroup;
26 
27 import androidx.test.InstrumentationRegistry;
28 import androidx.test.filters.LargeTest;
29 import androidx.test.rule.ActivityTestRule;
30 
31 import org.junit.Assert;
32 import org.junit.Rule;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 import org.junit.runners.Parameterized;
36 import org.junit.runners.Parameterized.Parameters;
37 
38 import java.util.Arrays;
39 import java.util.Collection;
40 
41 @LargeTest
42 @RunWith(Parameterized.class)
43 public class EditTextBackspacePerfTest {
44 
45     private static final String BOY = "\uD83D\uDC66";  // U+1F466
46     private static final String US_FLAG = "\uD83C\uDDFA\uD83C\uDDF8";  // U+1F1FA U+1F1F8
47     private static final String FAMILY =
48             // U+1F469 U+200D U+1F469 U+200D U+1F467 U+200D U+1F467
49             "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67";
50     private static final String EMOJI_MODIFIER = "\uD83C\uDFFD";  // U+1F3FD
51     private static final String KEYCAP = "\u20E3";
52     private static final String COLOR_COPYRIGHT = "\u00A9\uFE0F";
53 
54     @Parameters(name = "{0}")
cases()55     public static Collection cases() {
56         return Arrays.asList(new Object[][] {
57             { "Latin", "aaa", 1 },
58             { "Flags", US_FLAG + US_FLAG + US_FLAG, 4 },
59             { "EmojiModifier",
60                 BOY + EMOJI_MODIFIER + BOY + EMOJI_MODIFIER + BOY + EMOJI_MODIFIER, 4 },
61             { "KeyCap", "1" + KEYCAP + "1" + KEYCAP + "1" + KEYCAP, 2 },
62             { "ZwjSequence", FAMILY + FAMILY + FAMILY, 11 },
63             { "VariationSelector", COLOR_COPYRIGHT + COLOR_COPYRIGHT + COLOR_COPYRIGHT, 2 },
64         });
65     }
66 
67     private final String mMetricKey;
68     private final String mText;
69     private final int mCursorPos;
70 
71     private static final KeyEvent BACKSPACE_KEY_EVENT =
72             new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
73     private static final KeyEvent RIGHT_ARROW_KEY_EVENT =
74             new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT);
75 
EditTextBackspacePerfTest(String metricKey, String text, int cursorPos)76     public EditTextBackspacePerfTest(String metricKey, String text, int cursorPos) {
77         mMetricKey = metricKey;
78         mText = text;
79         mCursorPos = cursorPos;
80     }
81 
82     @Rule
83     public ActivityTestRule<PerfTestActivity> mActivityRule =
84             new ActivityTestRule<>(PerfTestActivity.class);
85 
86     @Rule
87     public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
88 
prepareTextForBackspace(EditText editText)89     private void prepareTextForBackspace(EditText editText) {
90         editText.setText(mText, TextView.BufferType.EDITABLE);
91         Selection.setSelection(editText.getText(), 0, 0);
92 
93         // Do layout it here since the cursor movement requires layout information but it
94         // happens asynchronously even if the view is attached to an Activity.
95         editText.setLayoutParams(new ViewGroup.LayoutParams(
96                 ViewGroup.LayoutParams.WRAP_CONTENT,
97                 ViewGroup.LayoutParams.WRAP_CONTENT));
98         editText.invalidate();
99         editText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
100                 MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
101         editText.layout(0, 0, 1024, 768);
102 
103         // mText contains three grapheme clusters. Move the cursor to the 2nd grapheme
104         // cluster by forwarding right arrow key event.
105         editText.onKeyDown(RIGHT_ARROW_KEY_EVENT.getKeyCode(), RIGHT_ARROW_KEY_EVENT);
106         Assert.assertEquals(mCursorPos, Selection.getSelectionStart(editText.getText()));
107     }
108 
109     @Test
testBackspace()110     public void testBackspace() {
111         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
112             EditText editText = new EditText(mActivityRule.getActivity());
113 
114             BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
115             while (state.keepRunning()) {
116                 // Prepare the test data for this iteration with pausing timer.
117                 state.pauseTiming();
118                 prepareTextForBackspace(editText);
119                 state.resumeTiming();
120 
121                 editText.onKeyDown(BACKSPACE_KEY_EVENT.getKeyCode(), BACKSPACE_KEY_EVENT);
122             }
123         });
124     }
125 }
126