Loading tests/WindowAnimationJank/Android.mk 0 → 100644 +31 −0 Original line number Diff line number Diff line # 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. LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := WindowAnimationJank LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator ub-janktesthelper LOCAL_SDK_VERSION := current include $(BUILD_PACKAGE) tests/WindowAnimationJank/AndroidManifest.xml 0 → 100644 +40 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- * 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. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.windowanimationjank"> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /> <application> <uses-library android:name="android.test.runner"/> <activity android:name="ElementLayoutActivity" android:label="ElementLayoutActivity" android:taskAffinity="android.windowanimationjank.ElementLayoutActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <!-- self-instrumenting test package. --> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="android.windowanimationjank"> </instrumentation> </manifest> tests/WindowAnimationJank/res/layout/flowlayout.xml 0 → 100644 +21 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- * 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. --> <android.windowanimationjank.FlowLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/root_flow_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" /> No newline at end of file tests/WindowAnimationJank/src/android/windowanimationjank/ElementLayoutActivity.java 0 → 100644 +159 −0 Original line number Diff line number Diff line /* * 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 android.windowanimationjank; import java.util.Random; import android.app.Activity; import android.os.Bundle; import android.view.ViewTreeObserver.OnPreDrawListener; import android.widget.Chronometer; import android.widget.RadioButton; import android.widget.Switch; import android.widget.TextView; import android.widget.ToggleButton; /* * Activity with arbitrary number of random UI elements, refresh itself constantly. */ public class ElementLayoutActivity extends Activity implements OnPreDrawListener { public final static String NUM_ELEMENTS_KEY = "num_elements"; private final static int DEFAULT_NUM_ELEMENTS = 100; private final static int BACKGROUND_COLOR = 0xfffff000; private final static int INDICATOR_COLOR = 0xffff0000; private FlowLayout mLayout; // Use the constant seed in order to get predefined order of elements. private Random mRandom = new Random(0); // Blinker indicator for visual feedback that Activity is currently updating. private TextView mIndicator; private static float mIndicatorState; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.flowlayout); mLayout = (FlowLayout)findViewById(R.id.root_flow_layout); mLayout.setBackgroundColor(BACKGROUND_COLOR); mIndicator = new TextView(this); mLayout.addView(mIndicator); mIndicator.setText("***\n***"); mIndicator.setBackgroundColor(BACKGROUND_COLOR); mIndicatorState = 0.0f; // Need constantly invalidate view in order to get max redraw rate. mLayout.getViewTreeObserver().addOnPreDrawListener(this); // Read requested number of elements in layout. int numElements = getIntent().getIntExtra(NUM_ELEMENTS_KEY, DEFAULT_NUM_ELEMENTS); for (int i = 0; i < numElements; ++i) { switch (mRandom.nextInt(5)) { case 0: createRadioButton(); break; case 1: createToggleButton(); break; case 2: createSwitch(); break; case 3: createTextView(); break; case 4: createChronometer(); break; } } setContentView(mLayout); } private void createTextView() { TextView textView = new TextView(this); int lineCnt = mRandom.nextInt(4); StringBuffer buffer = new StringBuffer(); for (int i = 0; i < lineCnt; ++i) { if (i != 0) { buffer.append("\n"); } buffer.append("Line:" + mRandom.nextInt()); } textView.setText(buffer); mLayout.addView(textView); } private void createRadioButton() { RadioButton button = new RadioButton(this); button.setText("RadioButton:" + mRandom.nextInt()); mLayout.addView(button); } private void createToggleButton() { ToggleButton button = new ToggleButton(this); button.setChecked(mRandom.nextBoolean()); mLayout.addView(button); } private void createSwitch() { Switch button = new Switch(this); button.setChecked(mRandom.nextBoolean()); mLayout.addView(button); } private void createChronometer() { Chronometer chronometer = new Chronometer(this); chronometer.setBase(mRandom.nextLong()); mLayout.addView(chronometer); chronometer.start(); } @Override protected void onResume() { super.onResume(); } @Override protected void onPause() { super.onPause(); } @Override public boolean onPreDraw() { // Interpolate indicator color int background = 0xff000000; for (int i = 0; i < 3; ++i) { int shift = 8 * i; int colorB = (BACKGROUND_COLOR >> shift) & 0xff; int colorI = (INDICATOR_COLOR >> shift) & 0xff; int color = (int)((float)colorB * (1.0f - mIndicatorState) + (float)colorI * mIndicatorState); if (color > 255) { color = 255; } background |= (color << shift); } mIndicator.setBackgroundColor(background); mIndicatorState += (3 / 60.0f); // around 3 times per second mIndicatorState = mIndicatorState - (int)mIndicatorState; mLayout.postInvalidate(); return true; } } No newline at end of file tests/WindowAnimationJank/src/android/windowanimationjank/FlowLayout.java 0 → 100644 +111 −0 Original line number Diff line number Diff line /* * 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 android.windowanimationjank; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; /** * Custom layout that place all elements in flows with and automatically wraps them. */ public class FlowLayout extends ViewGroup { private int mLineHeight; public FlowLayout(Context context) { super(context); } public FlowLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() -getPaddingRight(); int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom(); final int count = getChildCount(); int x = getPaddingLeft(); int y = getPaddingTop(); int lineHeight = 0; int childHeightMeasureSpec; if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); } else { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), childHeightMeasureSpec); final int childWidth = child.getMeasuredWidth(); lineHeight = Math.max(lineHeight, child.getMeasuredHeight()); if (x + childWidth > width) { x = getPaddingLeft(); y += lineHeight; } x += childWidth; } } mLineHeight = lineHeight; if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) { height = y + lineHeight; } else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) { if (y + lineHeight < height) { height = y + lineHeight; } } setMeasuredDimension(width, height); } @Override protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { if (p instanceof LayoutParams) { return true; } return false; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); final int width = r - l; int x = getPaddingLeft(); int y = getPaddingTop(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childWidth = child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); if (x + childWidth > width) { x = getPaddingLeft(); y += mLineHeight; } child.layout(x, y, x + childWidth, y + childHeight); x += childWidth; } } } } Loading
tests/WindowAnimationJank/Android.mk 0 → 100644 +31 −0 Original line number Diff line number Diff line # 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. LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := WindowAnimationJank LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator ub-janktesthelper LOCAL_SDK_VERSION := current include $(BUILD_PACKAGE)
tests/WindowAnimationJank/AndroidManifest.xml 0 → 100644 +40 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- * 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. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.windowanimationjank"> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /> <application> <uses-library android:name="android.test.runner"/> <activity android:name="ElementLayoutActivity" android:label="ElementLayoutActivity" android:taskAffinity="android.windowanimationjank.ElementLayoutActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <!-- self-instrumenting test package. --> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="android.windowanimationjank"> </instrumentation> </manifest>
tests/WindowAnimationJank/res/layout/flowlayout.xml 0 → 100644 +21 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- * 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. --> <android.windowanimationjank.FlowLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/root_flow_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" /> No newline at end of file
tests/WindowAnimationJank/src/android/windowanimationjank/ElementLayoutActivity.java 0 → 100644 +159 −0 Original line number Diff line number Diff line /* * 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 android.windowanimationjank; import java.util.Random; import android.app.Activity; import android.os.Bundle; import android.view.ViewTreeObserver.OnPreDrawListener; import android.widget.Chronometer; import android.widget.RadioButton; import android.widget.Switch; import android.widget.TextView; import android.widget.ToggleButton; /* * Activity with arbitrary number of random UI elements, refresh itself constantly. */ public class ElementLayoutActivity extends Activity implements OnPreDrawListener { public final static String NUM_ELEMENTS_KEY = "num_elements"; private final static int DEFAULT_NUM_ELEMENTS = 100; private final static int BACKGROUND_COLOR = 0xfffff000; private final static int INDICATOR_COLOR = 0xffff0000; private FlowLayout mLayout; // Use the constant seed in order to get predefined order of elements. private Random mRandom = new Random(0); // Blinker indicator for visual feedback that Activity is currently updating. private TextView mIndicator; private static float mIndicatorState; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.flowlayout); mLayout = (FlowLayout)findViewById(R.id.root_flow_layout); mLayout.setBackgroundColor(BACKGROUND_COLOR); mIndicator = new TextView(this); mLayout.addView(mIndicator); mIndicator.setText("***\n***"); mIndicator.setBackgroundColor(BACKGROUND_COLOR); mIndicatorState = 0.0f; // Need constantly invalidate view in order to get max redraw rate. mLayout.getViewTreeObserver().addOnPreDrawListener(this); // Read requested number of elements in layout. int numElements = getIntent().getIntExtra(NUM_ELEMENTS_KEY, DEFAULT_NUM_ELEMENTS); for (int i = 0; i < numElements; ++i) { switch (mRandom.nextInt(5)) { case 0: createRadioButton(); break; case 1: createToggleButton(); break; case 2: createSwitch(); break; case 3: createTextView(); break; case 4: createChronometer(); break; } } setContentView(mLayout); } private void createTextView() { TextView textView = new TextView(this); int lineCnt = mRandom.nextInt(4); StringBuffer buffer = new StringBuffer(); for (int i = 0; i < lineCnt; ++i) { if (i != 0) { buffer.append("\n"); } buffer.append("Line:" + mRandom.nextInt()); } textView.setText(buffer); mLayout.addView(textView); } private void createRadioButton() { RadioButton button = new RadioButton(this); button.setText("RadioButton:" + mRandom.nextInt()); mLayout.addView(button); } private void createToggleButton() { ToggleButton button = new ToggleButton(this); button.setChecked(mRandom.nextBoolean()); mLayout.addView(button); } private void createSwitch() { Switch button = new Switch(this); button.setChecked(mRandom.nextBoolean()); mLayout.addView(button); } private void createChronometer() { Chronometer chronometer = new Chronometer(this); chronometer.setBase(mRandom.nextLong()); mLayout.addView(chronometer); chronometer.start(); } @Override protected void onResume() { super.onResume(); } @Override protected void onPause() { super.onPause(); } @Override public boolean onPreDraw() { // Interpolate indicator color int background = 0xff000000; for (int i = 0; i < 3; ++i) { int shift = 8 * i; int colorB = (BACKGROUND_COLOR >> shift) & 0xff; int colorI = (INDICATOR_COLOR >> shift) & 0xff; int color = (int)((float)colorB * (1.0f - mIndicatorState) + (float)colorI * mIndicatorState); if (color > 255) { color = 255; } background |= (color << shift); } mIndicator.setBackgroundColor(background); mIndicatorState += (3 / 60.0f); // around 3 times per second mIndicatorState = mIndicatorState - (int)mIndicatorState; mLayout.postInvalidate(); return true; } } No newline at end of file
tests/WindowAnimationJank/src/android/windowanimationjank/FlowLayout.java 0 → 100644 +111 −0 Original line number Diff line number Diff line /* * 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 android.windowanimationjank; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; /** * Custom layout that place all elements in flows with and automatically wraps them. */ public class FlowLayout extends ViewGroup { private int mLineHeight; public FlowLayout(Context context) { super(context); } public FlowLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() -getPaddingRight(); int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom(); final int count = getChildCount(); int x = getPaddingLeft(); int y = getPaddingTop(); int lineHeight = 0; int childHeightMeasureSpec; if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); } else { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), childHeightMeasureSpec); final int childWidth = child.getMeasuredWidth(); lineHeight = Math.max(lineHeight, child.getMeasuredHeight()); if (x + childWidth > width) { x = getPaddingLeft(); y += lineHeight; } x += childWidth; } } mLineHeight = lineHeight; if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) { height = y + lineHeight; } else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) { if (y + lineHeight < height) { height = y + lineHeight; } } setMeasuredDimension(width, height); } @Override protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { if (p instanceof LayoutParams) { return true; } return false; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); final int width = r - l; int x = getPaddingLeft(); int y = getPaddingTop(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childWidth = child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); if (x + childWidth > width) { x = getPaddingLeft(); y += mLineHeight; } child.layout(x, y, x + childWidth, y + childHeight); x += childWidth; } } } }