summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/core/Android.mk1
-rw-r--r--apct-tests/perftests/core/res/layout/test_linear_layout.xml87
-rw-r--r--apct-tests/perftests/core/res/layout/test_linear_layout_weighted.xml89
-rw-r--r--apct-tests/perftests/core/res/layout/test_relative_layout.xml87
-rw-r--r--apct-tests/perftests/core/src/android/widget/LayoutPerfTest.java99
-rw-r--r--apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java13
-rw-r--r--apct-tests/perftests/utils/src/android/perftests/utils/LayoutUtils.java58
7 files changed, 430 insertions, 4 deletions
diff --git a/apct-tests/perftests/core/Android.mk b/apct-tests/perftests/core/Android.mk
index e9f18fd7d0ec..2fd6740e5719 100644
--- a/apct-tests/perftests/core/Android.mk
+++ b/apct-tests/perftests/core/Android.mk
@@ -3,6 +3,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test apct-perftests-utils
diff --git a/apct-tests/perftests/core/res/layout/test_linear_layout.xml b/apct-tests/perftests/core/res/layout/test_linear_layout.xml
new file mode 100644
index 000000000000..a863d1b51d05
--- /dev/null
+++ b/apct-tests/perftests/core/res/layout/test_linear_layout.xml
@@ -0,0 +1,87 @@
+<!--
+ Copyright (C) 2016 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/linear_layout_root"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <ImageButton
+ android:id="@+id/button"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true" />
+
+ <ImageButton
+ android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <ImageButton
+ android:id="@+id/button3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_centerVertical="true" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <ImageButton
+ android:id="@+id/button5"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentBottom="true" />
+ </LinearLayout>
+
+ <ImageButton
+ android:id="@+id/button4"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@+id/button2"
+ android:layout_centerHorizontal="true" />
+
+ <ImageButton
+ android:id="@+id/button6"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_above="@+id/button4"
+ android:layout_centerHorizontal="true" />
+
+ <ImageButton
+ android:id="@+id/button7"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@+id/button"
+ android:layout_toEndOf="@+id/button"
+ android:layout_toRightOf="@+id/button" />
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/apct-tests/perftests/core/res/layout/test_linear_layout_weighted.xml b/apct-tests/perftests/core/res/layout/test_linear_layout_weighted.xml
new file mode 100644
index 000000000000..77a982c5c54f
--- /dev/null
+++ b/apct-tests/perftests/core/res/layout/test_linear_layout_weighted.xml
@@ -0,0 +1,89 @@
+<!--
+ Copyright (C) 2016 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/linear_layout_weighted_root"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <ImageButton
+ android:id="@+id/button"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true" />
+
+ <ImageButton
+ android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <ImageButton
+ android:id="@+id/button3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="2"
+ android:layout_alignParentLeft="true"
+ android:layout_centerVertical="true" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <ImageButton
+ android:id="@+id/button5"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:layout_alignParentBottom="true" />
+ </LinearLayout>
+
+ <ImageButton
+ android:id="@+id/button4"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@+id/button2"
+ android:layout_centerHorizontal="true" />
+
+ <ImageButton
+ android:id="@+id/button6"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_above="@+id/button4"
+ android:layout_centerHorizontal="true" />
+
+ <ImageButton
+ android:id="@+id/button7"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@+id/button"
+ android:layout_toEndOf="@+id/button"
+ android:layout_toRightOf="@+id/button" />
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/apct-tests/perftests/core/res/layout/test_relative_layout.xml b/apct-tests/perftests/core/res/layout/test_relative_layout.xml
new file mode 100644
index 000000000000..1daf93aaaf07
--- /dev/null
+++ b/apct-tests/perftests/core/res/layout/test_relative_layout.xml
@@ -0,0 +1,87 @@
+<!--
+ Copyright (C) 2016 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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/relative_layout_root"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <ImageButton
+ android:id="@+id/button"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true" />
+
+ <ImageButton
+ android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true" />
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <ImageButton
+ android:id="@+id/button3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_centerVertical="true" />
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <ImageButton
+ android:id="@+id/button5"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentBottom="true" />
+ </RelativeLayout>
+
+ <ImageButton
+ android:id="@+id/button4"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@+id/button2"
+ android:layout_centerHorizontal="true" />
+
+ <ImageButton
+ android:id="@+id/button6"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_above="@+id/button4"
+ android:layout_centerHorizontal="true" />
+
+ <ImageButton
+ android:id="@+id/button7"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@+id/button"
+ android:layout_toEndOf="@+id/button"
+ android:layout_toRightOf="@+id/button" />
+ </RelativeLayout>
+
+</RelativeLayout> \ No newline at end of file
diff --git a/apct-tests/perftests/core/src/android/widget/LayoutPerfTest.java b/apct-tests/perftests/core/src/android/widget/LayoutPerfTest.java
new file mode 100644
index 000000000000..db15e9bbe4b6
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/widget/LayoutPerfTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 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 android.app.Activity;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.perftests.utils.StubActivity;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.LargeTest;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.core.frameworks.perftests.R;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import static android.perftests.utils.LayoutUtils.gatherViewTree;
+import static android.perftests.utils.LayoutUtils.requestLayoutForAllNodes;
+import static android.view.View.MeasureSpec.AT_MOST;
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.UNSPECIFIED;
+
+@LargeTest
+@RunWith(Parameterized.class)
+public class LayoutPerfTest {
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection measureSpecs() {
+ return Arrays.asList(new Object[][] {
+ { "relative", R.layout.test_relative_layout, R.id.relative_layout_root },
+ { "linear", R.layout.test_linear_layout, R.id.linear_layout_root },
+ { "linear_weighted", R.layout.test_linear_layout_weighted,
+ R.id.linear_layout_weighted_root },
+ });
+ }
+
+ private int[] mMeasureSpecs = {EXACTLY, AT_MOST, UNSPECIFIED};
+
+ private int mLayoutId;
+ private int mViewId;
+
+ public LayoutPerfTest(String key, int layoutId, int viewId) {
+ // key is used in the final report automatically.
+ mLayoutId = layoutId;
+ mViewId = viewId;
+ }
+
+ @Rule
+ public ActivityTestRule<StubActivity> mActivityRule =
+ new ActivityTestRule(StubActivity.class);
+
+ @Rule
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ @UiThreadTest
+ public void testLayoutPerf() {
+ Activity activity = mActivityRule.getActivity();
+ activity.setContentView(mLayoutId);
+
+ ViewGroup viewGroup = (ViewGroup) activity.findViewById(mViewId);
+
+ List<View> allNodes = gatherViewTree(viewGroup);
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+ int length = mMeasureSpecs.length;
+ while (state.keepRunning()) {
+ for (int i = 0; i < length; i++) {
+ // The overhead of this call is ignorable, like within 1% difference.
+ requestLayoutForAllNodes(allNodes);
+
+ viewGroup.measure(mMeasureSpecs[i % length], mMeasureSpecs[i % length]);
+ viewGroup.layout(0, 0, viewGroup.getMeasuredWidth(), viewGroup.getMeasuredHeight());
+ }
+ }
+ }
+}
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
index 2c5a9eac481d..4213e4a3aa2b 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
@@ -176,10 +176,15 @@ public class BenchmarkState {
private String summaryLine() {
StringBuilder sb = new StringBuilder();
sb.append("Summary: ");
- sb.append("median=" + median() + "ns, ");
- sb.append("mean=" + mean() + "ns, ");
- sb.append("sigma=" + standardDeviation() + ", ");
- sb.append("iteration=" + mResults.size());
+ sb.append("median=").append(median()).append("ns, ");
+ sb.append("mean=").append(mean()).append("ns, ");
+ sb.append("sigma=").append(standardDeviation()).append(", ");
+ sb.append("iteration=").append(mResults.size()).append(", ");
+ // print out the first few iterations' number for double checking.
+ int sampleNumber = Math.min(mResults.size(), MIN_REPEAT_TIMES);
+ for (int i = 0; i < sampleNumber; i++) {
+ sb.append("No ").append(i).append(" result is ").append(mResults.get(i)).append(", ");
+ }
return sb.toString();
}
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/LayoutUtils.java b/apct-tests/perftests/utils/src/android/perftests/utils/LayoutUtils.java
new file mode 100644
index 000000000000..c64af8fccb36
--- /dev/null
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/LayoutUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 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.perftests.utils;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LayoutUtils {
+
+ private static void recursivelyGather(ViewGroup currentNode, List<View> nodeList) {
+ nodeList.add(currentNode);
+ int count = currentNode.getChildCount();
+ for (int i = 0; i < count; i++) {
+ View view = currentNode.getChildAt(i);
+ if (view instanceof ViewGroup) {
+ recursivelyGather((ViewGroup) view, nodeList);
+ } else {
+ nodeList.add(view);
+ }
+ }
+ }
+
+ /**
+ * Flattern the whole view tree into a list of View.
+ */
+ public static List<View> gatherViewTree(ViewGroup root) {
+ List<View> result = new ArrayList<View>();
+ recursivelyGather(root, result);
+ return result;
+ }
+
+ /**
+ * For every node in the list, call requestLayout.
+ */
+ public static void requestLayoutForAllNodes(List<View> nodeList) {
+ int count = nodeList.size();
+ for (int i = 0; i < count; i++) {
+ nodeList.get(i).requestLayout();
+ }
+ }
+}