Add tests for text layout cache
Change-Id: I605391de1e0772821dd2a5ad6f829aea1f63c25b
diff --git a/tests/UiBench/AndroidManifest.xml b/tests/UiBench/AndroidManifest.xml
index f892a68..9b3d186 100644
--- a/tests/UiBench/AndroidManifest.xml
+++ b/tests/UiBench/AndroidManifest.xml
@@ -121,5 +121,21 @@
<category android:name="com.android.test.uibench.TEST" />
</intent-filter>
</activity>
+ <activity
+ android:name=".TextCacheLowHitrateActivity"
+ android:label="Text/Layout Cache Low Hitrate" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.android.test.uibench.TEST" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name=".TextCacheHighHitrateActivity"
+ android:label="Text/Layout Cache High Hitrate" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.android.test.uibench.TEST" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/tests/UiBench/src/com/android/test/uibench/CompatListActivity.java b/tests/UiBench/src/com/android/test/uibench/CompatListActivity.java
new file mode 100644
index 0000000..40ec453
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/CompatListActivity.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 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.test.uibench;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.ListFragment;
+import android.support.v7.app.AppCompatActivity;
+import android.widget.ListAdapter;
+
+public abstract class CompatListActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ FragmentManager fm = getSupportFragmentManager();
+ if (fm.findFragmentById(android.R.id.content) == null) {
+ ListFragment listFragment = new ListFragment();
+ listFragment.setListAdapter(createListAdapter());
+ fm.beginTransaction().add(android.R.id.content, listFragment).commit();
+ }
+ }
+
+ protected abstract ListAdapter createListAdapter();
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/DialogListActivity.java b/tests/UiBench/src/com/android/test/uibench/DialogListActivity.java
index 7b579a1..fe712d5 100644
--- a/tests/UiBench/src/com/android/test/uibench/DialogListActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/DialogListActivity.java
@@ -28,7 +28,7 @@
ListView listView = new ListView(this);
listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
- TrivialListActivity.buildStringList()));
+ TextUtils.buildSimpleStringList()));
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Dialog");
diff --git a/tests/UiBench/src/com/android/test/uibench/InflatingListActivity.java b/tests/UiBench/src/com/android/test/uibench/InflatingListActivity.java
index 798c226..84383ec 100644
--- a/tests/UiBench/src/com/android/test/uibench/InflatingListActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/InflatingListActivity.java
@@ -15,19 +15,16 @@
*/
package com.android.test.uibench;
-import android.os.Bundle;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.ListFragment;
-import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
-public class InflatingListActivity extends AppCompatActivity {
- private ListAdapter createListAdapter() {
+public class InflatingListActivity extends CompatListActivity {
+ @Override
+ protected ListAdapter createListAdapter() {
return new ArrayAdapter<String>(this,
- android.R.layout.simple_list_item_1, TrivialListActivity.buildStringList()) {
+ android.R.layout.simple_list_item_1, TextUtils.buildSimpleStringList()) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// pathological getView behavior: drop convertView on the floor to force inflation
@@ -35,16 +32,4 @@
}
};
}
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- FragmentManager fm = getSupportFragmentManager();
- if (fm.findFragmentById(android.R.id.content) == null) {
- ListFragment listFragment = new ListFragment();
- listFragment.setListAdapter(createListAdapter());
- fm.beginTransaction().add(android.R.id.content, listFragment).commit();
- }
- }
}
diff --git a/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java b/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java
index e39ec03..d32f071 100644
--- a/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java
@@ -38,7 +38,7 @@
};
listFragment.setListAdapter(new ArrayAdapter<>(this,
- R.layout.card_row, R.id.card_text, TrivialListActivity.buildStringList()));
+ R.layout.card_row, R.id.card_text, TextUtils.buildSimpleStringList()));
fm.beginTransaction().add(android.R.id.content, listFragment).commit();
}
}
diff --git a/tests/UiBench/src/com/android/test/uibench/TextCacheHighHitrateActivity.java b/tests/UiBench/src/com/android/test/uibench/TextCacheHighHitrateActivity.java
new file mode 100644
index 0000000..91d74ac
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/TextCacheHighHitrateActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 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.test.uibench;
+
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+
+public class TextCacheHighHitrateActivity extends CompatListActivity {
+ @Override
+ protected ListAdapter createListAdapter() {
+ return new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
+ TextUtils.buildParagraphListWithHitPercentage(80));
+ }
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/TextCacheLowHitrateActivity.java b/tests/UiBench/src/com/android/test/uibench/TextCacheLowHitrateActivity.java
new file mode 100644
index 0000000..b526cde
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/TextCacheLowHitrateActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 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.test.uibench;
+
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+
+public class TextCacheLowHitrateActivity extends CompatListActivity {
+ @Override
+ protected ListAdapter createListAdapter() {
+ return new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
+ TextUtils.buildParagraphListWithHitPercentage(20));
+ }
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/TextUtils.java b/tests/UiBench/src/com/android/test/uibench/TextUtils.java
new file mode 100644
index 0000000..d88ca1e
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/TextUtils.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015 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.test.uibench;
+
+import java.util.Random;
+
+public class TextUtils {
+ private static final int STRING_COUNT = 200;
+ private static final int SIMPLE_STRING_LENGTH = 10;
+
+ /**
+ * Create word of random assortment of lower/upper case letters
+ */
+ private static String randomWord(Random random, int length) {
+ String result = "";
+ for (int j = 0; j < length; j++) {
+ // add random letter
+ int base = random.nextInt(2) == 0 ? 'A' : 'a';
+ result += (char)(random.nextInt(26) + base);
+ }
+ return result;
+ }
+
+ public static String[] buildSimpleStringList() {
+ String[] strings = new String[STRING_COUNT];
+ Random random = new Random(0);
+ for (int i = 0; i < strings.length; i++) {
+ strings[i] = randomWord(random, SIMPLE_STRING_LENGTH);
+ }
+ return strings;
+ }
+
+ // a small number of strings reused frequently, expected to hit
+ // in the word-granularity text layout cache
+ static final String[] CACHE_HIT_STRINGS = new String[] {
+ "a",
+ "small",
+ "number",
+ "of",
+ "strings",
+ "reused",
+ "frequently"
+ };
+
+ private static final int WORDS_IN_PARAGRAPH = 150;
+
+ // misses are fairly long 'words' to ensure they miss
+ private static final int PARAGRAPH_MISS_MIN_LENGTH = 4;
+ private static final int PARAGRAPH_MISS_MAX_LENGTH = 9;
+
+ static String[] buildParagraphListWithHitPercentage(int hitPercentage) {
+ if (hitPercentage < 0 || hitPercentage > 100) throw new IllegalArgumentException();
+
+ String[] strings = new String[STRING_COUNT];
+ Random random = new Random(0);
+ for (int i = 0; i < strings.length; i++) {
+ String result = "";
+ for (int word = 0; word < WORDS_IN_PARAGRAPH; word++) {
+ if (word != 0) {
+ result += " ";
+ }
+ if (random.nextInt(100) < hitPercentage) {
+ // add a common word, which is very likely to hit in the cache
+ result += CACHE_HIT_STRINGS[random.nextInt(CACHE_HIT_STRINGS.length)];
+ } else {
+ // construct a random word, which will *most likely* miss
+ int length = PARAGRAPH_MISS_MIN_LENGTH;
+ length += random.nextInt(PARAGRAPH_MISS_MAX_LENGTH - PARAGRAPH_MISS_MIN_LENGTH);
+
+ result += randomWord(random, length);
+ }
+ }
+ strings[i] = result;
+ }
+
+ return strings;
+ }
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/TrivialListActivity.java b/tests/UiBench/src/com/android/test/uibench/TrivialListActivity.java
index 9c8ae9b..339ac80 100644
--- a/tests/UiBench/src/com/android/test/uibench/TrivialListActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/TrivialListActivity.java
@@ -15,41 +15,13 @@
*/
package com.android.test.uibench;
-import android.os.Bundle;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.ListFragment;
-import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
-import java.util.Random;
-
-public class TrivialListActivity extends AppCompatActivity {
- static final int STRING_LENGTH = 10;
-
- static String[] buildStringList() {
- String[] strings = new String[200];
- Random random = new Random(0);
- for (int i = 0; i < strings.length; i++) {
- String result = "";
- for (int j = 0; j < STRING_LENGTH; j++) {
- // add random letter
- result += (char)(random.nextInt(26) + 65);
- }
- strings[i] = result;
- }
- return strings;
- }
-
+public class TrivialListActivity extends CompatListActivity {
@Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- FragmentManager fm = getSupportFragmentManager();
- if (fm.findFragmentById(android.R.id.content) == null) {
- ListFragment listFragment = new ListFragment();
- listFragment.setListAdapter(new ArrayAdapter<>(this,
- android.R.layout.simple_list_item_1, buildStringList()));
- fm.beginTransaction().add(android.R.id.content, listFragment).commit();
- }
+ protected ListAdapter createListAdapter() {
+ return new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
+ TextUtils.buildSimpleStringList());
}
}