Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e519110 authored by Yury Khmel's avatar Yury Khmel Committed by Android (Google) Code Review
Browse files

Merge "Jank test for full-screen activity orientation change."

parents aeaa12c3 4f26c041
Loading
Loading
Loading
Loading
+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)
+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>
+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
+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
+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