Merge "Terminate Looper if Video Snapshot Not Supported"
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index fcbe969..840d42b 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -50,6 +50,7 @@
CtsMediaTestCases \
CtsNdefTestCases \
CtsNetTestCases \
+ CtsOpenGlPerfTestCases \
CtsOsTestCases \
CtsPermissionTestCases \
CtsPermission2TestCases \
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/PlayVideoActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/PlayVideoActivity.java
index 2b65421..369d32c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/PlayVideoActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/PlayVideoActivity.java
@@ -69,8 +69,6 @@
private Handler mHandler = new Handler();
private int mVideoWidth;
private int mVideoHeight;
- private boolean mIsVideoSizeKnown = false;
- private boolean mIsVideoReadyToBePlayed = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -170,17 +168,14 @@
@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
- mVideoWidth = width;
- mVideoHeight = height;
- mIsVideoSizeKnown = true;
- if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
- startVideoPlayback();
+ if (width != 0 && height != 0) {
+ mVideoWidth = width;
+ mVideoHeight = height;
+ fillScreen();
}
}
private void startVideoPlayback() {
- mHolder.setFixedSize(mVideoWidth, mVideoHeight);
- fillScreen();
mPlayer.start();
// Enable Pass button after 60 seconds
@@ -189,13 +184,11 @@
@Override
public void onPrepared(MediaPlayer mp) {
- mIsVideoReadyToBePlayed = true;
- if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
- startVideoPlayback();
- }
+ startVideoPlayback();
}
private void fillScreen() {
+ mHolder.setFixedSize(mVideoWidth, mVideoHeight);
Rect rect = new Rect();
mVideoFrame.getDrawingRect(rect);
LayoutParams lp = mSurfaceView.getLayoutParams();
diff --git a/tests/tests/animation/src/android/animation/cts/AnimationActivity.java b/tests/tests/animation/src/android/animation/cts/AnimationActivity.java
index ee3202e..43679c8 100644
--- a/tests/tests/animation/src/android/animation/cts/AnimationActivity.java
+++ b/tests/tests/animation/src/android/animation/cts/AnimationActivity.java
@@ -58,7 +58,6 @@
float mDeltaY = 200f;
long mDuration = 1000;
public AnimationView view = null;
- private boolean isAnimationRunning = false;
@Override
public void onCreate(Bundle bundle){
@@ -92,12 +91,12 @@
}
public ValueAnimator createAnimatorWithRepeatMode(int repeatMode) {
- return createAnimator(view.newBall, "y", 1000,ValueAnimator.INFINITE, repeatMode,
+ return createAnimator(view.newBall, "y", 1000, ValueAnimator.INFINITE, repeatMode,
new AccelerateInterpolator(), mStartY, mStartY + mDeltaY);
}
public ValueAnimator createAnimatorWithRepeatCount(int repeatCount) {
- return createAnimator(view.newBall, "y", 1000,repeatCount, ValueAnimator.REVERSE,
+ return createAnimator(view.newBall, "y", 1000, repeatCount, ValueAnimator.REVERSE,
new AccelerateInterpolator(), mStartY, mStartY + mDeltaY);
}
@@ -106,46 +105,98 @@
ValueAnimator.REVERSE,new AccelerateInterpolator(), mStartY, mStartY + mDeltaY);
}
+ public ValueAnimator createAnimatorWithInterpolator(TimeInterpolator interpolator){
+ return createAnimator(view.newBall, "y", 1000, ValueAnimator.INFINITE, ValueAnimator.REVERSE,
+ interpolator, mStartY, mStartY + mDeltaY);
+ }
+
+ public ValueAnimator createObjectAnimatorForInt(Object object,String propertyName,
+ long duration, int repeatCount, int repeatMode, TimeInterpolator timeInterpolator,
+ int start, int end) {
+ ObjectAnimator objAnimator = ObjectAnimator.ofInt(object, propertyName, start,end);
+ objAnimator.setDuration(duration);
+
+ objAnimator.setRepeatCount(repeatCount);
+ objAnimator.setInterpolator(timeInterpolator);
+ objAnimator.setRepeatMode(repeatMode);
+ return objAnimator;
+ }
+
+ public ValueAnimator createObjectAnimatorForInt() {
+ ObjectAnimator objAnimator = ObjectAnimator.ofInt(view.newBall, "y", (int)mStartY,
+ (int)(mStartY + mDeltaY));
+ objAnimator.setDuration(mDuration);
+
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(new AccelerateInterpolator());
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ return objAnimator;
+ }
+
public void startAnimation(long duration){
ValueAnimator bounceAnimator = ObjectAnimator.ofFloat(view.newBall, "y", mStartY,
- mStartY + mDeltaY);
+ mStartY + mDeltaY);
bounceAnimator.setDuration(duration);
bounceAnimator.setRepeatCount(ValueAnimator.INFINITE);
bounceAnimator.setInterpolator(new AccelerateInterpolator());
bounceAnimator.setRepeatMode(ValueAnimator.REVERSE);
view.bounceAnimator = bounceAnimator;
+ view.startColorAnimator();
view.animateBall();
}
public void startAnimation(ValueAnimator valueAnimator){
view.bounceAnimator = valueAnimator;
+ view.startColorAnimator();
view.animateBall();
- isAnimationRunning = true;
+ }
+
+ public void startAnimation(ObjectAnimator bounceAnimator) {
+ view.bounceAnimator = bounceAnimator;
+ view.startColorAnimator();
+ view.animateBall();
+ }
+
+ public void startAnimation(ObjectAnimator bounceAnimator, ObjectAnimator colorAnimator) {
+ view.bounceAnimator = bounceAnimator;
+ view.startColorAnimator(colorAnimator);
+ view.animateBall();
+ }
+
+ public void startColorAnimation(ValueAnimator colorAnimator){
+ view.startColorAnimator(colorAnimator);
}
public class AnimationView extends View {
- private static final int RED = 0xffFF8080;
- private static final int BLUE = 0xff8080FF;
+ public static final int RED = 0xffFF8080;
+ public static final int BLUE = 0xff8080FF;
public ShapeHolder newBall = null;
public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
AnimatorSet animation = null;
public ValueAnimator bounceAnimator;
+ public ValueAnimator colorAnimator;
public AnimationView(Context context) {
super(context);
- ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE);
- colorAnim.setDuration(1000);
- colorAnim.setEvaluator(new ArgbEvaluator());
- colorAnim.setRepeatCount(1);
- colorAnim.setRepeatMode(ValueAnimator.REVERSE);
- colorAnim.start();
newBall = addBall(mBallHeight, mBallWidth);
}
+ public void startColorAnimator() {
+ colorAnimator = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE);
+ colorAnimator.setDuration(1000);
+ colorAnimator.setEvaluator(new ArgbEvaluator());
+ colorAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ colorAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ colorAnimator.start();
+ }
+
+ public void startColorAnimator(ValueAnimator animator) {
+ this.colorAnimator = animator;
+ colorAnimator.start();
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
-
-
return true;
}
@@ -203,4 +254,3 @@
}
}
}
-
diff --git a/tests/tests/animation/src/android/animation/cts/ArgbEvaluatorTest.java b/tests/tests/animation/src/android/animation/cts/ArgbEvaluatorTest.java
new file mode 100644
index 0000000..33c3716
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/ArgbEvaluatorTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 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.animation.cts;
+
+import android.animation.ArgbEvaluator;
+import android.graphics.Color;
+import android.test.InstrumentationTestCase;
+
+public class ArgbEvaluatorTest extends InstrumentationTestCase {
+ public void testEvaluate() throws Throwable {
+ final int RED = 0xffFF8080;
+ final int BLUE = 0xff8080FF;
+ int aRED = Color.alpha(RED);
+ int rRED = Color.red(RED);
+ int gRED = Color.green(RED);
+ int bRED = Color.blue(RED);
+ int aBLUE = Color.alpha(BLUE);
+ int rBLUE = Color.red(BLUE);
+ int gBLUE = Color.green(BLUE);
+ int bBLUE = Color.blue(BLUE);
+
+ final ArgbEvaluator evaluator = new ArgbEvaluator();
+ class AnimationRunnable implements Runnable{
+ int result;
+ public void run() {
+ result = (Integer) evaluator.evaluate(0.5f, RED, BLUE);
+ }
+ }
+ AnimationRunnable aRunnable = new AnimationRunnable();
+ this.runTestOnUiThread(aRunnable);
+ Thread.sleep(100);
+ int result = aRunnable.result;
+
+ int aResult = Color.alpha(result);
+ int rResult = Color.red(result);
+ int gResult = Color.green(result);
+ int bResult = Color.blue(result);
+ assertTrue(aResult >= aRED);
+ assertTrue(aResult <= aBLUE);
+ assertTrue(rResult <= rRED);
+ assertTrue(rResult >= rBLUE);
+ assertTrue(gResult >= gRED);
+ assertTrue(gResult <= gBLUE);
+ assertTrue(bResult >= bRED);
+ assertTrue(bResult <= bBLUE);
+ }
+}
+
diff --git a/tests/tests/animation/src/android/animation/cts/FloatEvaluatorTest.java b/tests/tests/animation/src/android/animation/cts/FloatEvaluatorTest.java
new file mode 100644
index 0000000..8cc1ffe
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/FloatEvaluatorTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 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.animation.cts;
+
+import android.animation.FloatEvaluator;
+import android.test.InstrumentationTestCase;
+
+public class FloatEvaluatorTest extends InstrumentationTestCase {
+ public void testEvaluate() {
+ float start = 0.0f;
+ float end = 1.0f;
+ float fraction = 0.5f;
+ FloatEvaluator floatEvaluator = new FloatEvaluator();
+ float result = floatEvaluator.evaluate(fraction, start, end);
+ assertTrue(result >= (fraction*start));
+ assertTrue(result <= (fraction*end));
+ }
+}
+
diff --git a/tests/tests/animation/src/android/animation/cts/IntEvaluatorTest.java b/tests/tests/animation/src/android/animation/cts/IntEvaluatorTest.java
new file mode 100644
index 0000000..11df20c
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/IntEvaluatorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 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.animation.cts;
+
+import android.animation.IntEvaluator;
+import android.test.InstrumentationTestCase;
+
+public class IntEvaluatorTest extends InstrumentationTestCase {
+ public void testEvaluate() throws Throwable {
+ final int start = 0;
+ final int end = 100;
+ final float fraction = 0.5f;
+ final IntEvaluator intEvaluator = new IntEvaluator();
+ class AnimationRunnable implements Runnable{
+ int result;
+ public void run() {
+ result = intEvaluator.evaluate(fraction, start, end);
+ }
+ }
+ AnimationRunnable aRunnable = new AnimationRunnable();
+ this.runTestOnUiThread(aRunnable);
+ Thread.sleep(1);
+ int result = aRunnable.result;
+ assertTrue(result >= (fraction*start));
+ assertTrue(result <= (fraction*end));
+ }
+}
+
diff --git a/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
new file mode 100644
index 0000000..be5c1d4
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2011 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.animation.cts;
+
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Property;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Interpolator;
+
+public class ObjectAnimatorTest extends
+ ActivityInstrumentationTestCase2<AnimationActivity> {
+ private AnimationActivity mActivity;
+ private ObjectAnimator mObjectAnimator;
+ private long mDuration = 1000;
+
+ public ObjectAnimatorTest() {
+ super(AnimationActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ setActivityInitialTouchMode(false);
+ mActivity = getActivity();
+ mObjectAnimator = (ObjectAnimator) mActivity.createAnimatorWithDuration(mDuration);
+ }
+
+ public void testDuration() throws Throwable {
+ final long duration = 2000;
+ ObjectAnimator objectAnimatorLocal = (ObjectAnimator)mActivity.createAnimatorWithDuration(
+ duration);
+ startAnimation(objectAnimatorLocal);
+ assertEquals(duration, objectAnimatorLocal.getDuration());
+ }
+ public void testOfFloat() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ ObjectAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ assertTrue(objAnimator != null);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(new AccelerateInterpolator());
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ startAnimation(objAnimator);
+ assertTrue(objAnimator != null);
+ Thread.sleep(100);
+ float x = mActivity.view.newBall.getX();
+ float y = mActivity.view.newBall.getY();
+ assertTrue( y >= startY);
+ assertTrue( y <= endY);
+ }
+
+ public void testOfFloatBase() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ ObjectAnimator animator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ ObjectAnimator objAnimator = new ObjectAnimator();
+ objAnimator.setTarget(object);
+ objAnimator.setPropertyName(property);
+ assertEquals(animator.getTarget(), objAnimator.getTarget());
+ assertEquals(animator.getPropertyName(), objAnimator.getPropertyName());
+ }
+
+ public void testOfInt() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+
+ ObjectAnimator colorAnimator = ObjectAnimator.ofInt(object, property,
+ startColor, endColor);
+ colorAnimator.setDuration(1000);
+ colorAnimator.setEvaluator(new ArgbEvaluator());
+ colorAnimator.setRepeatCount(1);
+ colorAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ colorAnimator.start();
+ startAnimation(mObjectAnimator, colorAnimator);
+ Thread.sleep(100);
+ Integer i = (Integer) colorAnimator.getAnimatedValue();
+ //We are going from less negative value to a more negative value
+ assertTrue(i.intValue() <= startColor);
+ assertTrue(endColor <= i.intValue());
+ }
+
+ public void testOfObject() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+ Object[] values = {new Integer(startColor), new Integer(endColor)};
+ ArgbEvaluator evaluator = new ArgbEvaluator();
+ ObjectAnimator colorAnimator = ObjectAnimator.ofObject(object, property,
+ evaluator, values);
+ colorAnimator.setDuration(1000);
+ colorAnimator.setRepeatCount(1);
+ colorAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ colorAnimator.start();
+ startAnimation(mObjectAnimator, colorAnimator);
+ Thread.sleep(100);
+ Integer i = (Integer) colorAnimator.getAnimatedValue();
+ //We are going from less negative value to a more negative value
+ assertTrue(i.intValue() <= startColor);
+ assertTrue(endColor <= i.intValue());
+ }
+
+ public void testOfPropertyValuesHolder() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String propertyName = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+ int values[] = {startColor, endColor};
+ ArgbEvaluator evaluator = new ArgbEvaluator();
+ PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofInt(propertyName, values);
+ ObjectAnimator colorAnimator = ObjectAnimator.ofPropertyValuesHolder(object,
+ propertyValuesHolder);
+ colorAnimator.setDuration(1000);
+ colorAnimator.setRepeatCount(1);
+ colorAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ colorAnimator.start();
+ startAnimation(mObjectAnimator, colorAnimator);
+ Thread.sleep(100);
+ Integer i = (Integer) colorAnimator.getAnimatedValue();
+ //We are going from less negative value to a more negative value
+ assertTrue(i.intValue() <= startColor);
+ assertTrue(endColor <= i.intValue());
+ }
+
+ public void testGetPropertyName() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String propertyName = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+ Object[] values = {new Integer(startColor), new Integer(endColor)};
+ ArgbEvaluator evaluator = new ArgbEvaluator();
+ ObjectAnimator colorAnimator = ObjectAnimator.ofObject(object, propertyName,
+ evaluator, values);
+ String actualPropertyName = colorAnimator.getPropertyName();
+ assertEquals(propertyName, actualPropertyName);
+ }
+
+ public void testSetCurrentPlayTime() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String propertyName = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+ long playTime = 10000l;
+ Object[] values = {new Integer(startColor), new Integer(endColor)};
+ ArgbEvaluator evaluator = new ArgbEvaluator();
+ ObjectAnimator colorAnimator = ObjectAnimator.ofObject(object, propertyName,
+ evaluator, values);
+ colorAnimator.setCurrentPlayTime(playTime);
+ long actualPlayTime = colorAnimator.getCurrentPlayTime();
+ assertEquals(playTime, actualPlayTime);
+ }
+
+ public void testSetFloatValues() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ float[] values = {startY, endY};
+ ObjectAnimator objAnimator = new ObjectAnimator();
+ objAnimator.setTarget(object);
+ objAnimator.setPropertyName(property);
+ objAnimator.setFloatValues(values);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(new AccelerateInterpolator());
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ startAnimation(objAnimator);
+ Thread.sleep(100);
+ float y = mActivity.view.newBall.getY();
+ assertTrue( y >= startY);
+ assertTrue( y <= endY);
+ }
+
+ public void testGetTarget() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String propertyName = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+ Object[] values = {new Integer(startColor), new Integer(endColor)};
+ ArgbEvaluator evaluator = new ArgbEvaluator();
+ ObjectAnimator colorAnimator = ObjectAnimator.ofObject(object, propertyName,
+ evaluator, values);
+ Object target = colorAnimator.getTarget();
+ assertEquals(object, target);
+ }
+
+ public void testClone() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ Interpolator interpolator = new AccelerateInterpolator();
+ ObjectAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(interpolator);
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ ObjectAnimator cloneAnimator = objAnimator.clone();
+
+ assertEquals(mDuration, cloneAnimator.getDuration());
+ assertEquals(ValueAnimator.INFINITE, cloneAnimator.getRepeatCount());
+ assertEquals(ValueAnimator.REVERSE, cloneAnimator.getRepeatMode());
+ assertEquals(object, cloneAnimator.getTarget());
+ assertEquals(property, cloneAnimator.getPropertyName());
+ assertEquals(interpolator, cloneAnimator.getInterpolator());
+ }
+
+ public void testIsStarted() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ Interpolator interpolator = new AccelerateInterpolator();
+ ObjectAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(interpolator);
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ startAnimation(objAnimator);
+ Thread.sleep(100);
+ assertTrue(objAnimator.isStarted());
+ Thread.sleep(100);
+ }
+
+ private void startAnimation(final ObjectAnimator mObjectAnimator) throws Throwable {
+ Thread mAnimationRunnable = new Thread() {
+ public void run() {
+ mActivity.startAnimation(mObjectAnimator);
+ }
+ };
+ this.runTestOnUiThread(mAnimationRunnable);
+ }
+ private void startAnimation(final ObjectAnimator mObjectAnimator, final
+ ObjectAnimator colorAnimator) throws Throwable {
+ Thread mAnimationRunnable = new Thread() {
+ public void run() {
+ mActivity.startAnimation(mObjectAnimator, colorAnimator);
+ }
+ };
+ this.runTestOnUiThread(mAnimationRunnable);
+ }
+}
+
+
diff --git a/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
index 314c06d..a7626bc 100644
--- a/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
+++ b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
@@ -15,24 +15,22 @@
*/
package android.animation.cts;
+import android.animation.ArgbEvaluator;
+import android.animation.FloatEvaluator;
+import android.animation.IntEvaluator;
+import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
-import android.app.Instrumentation;
-import android.content.Intent;
import android.test.ActivityInstrumentationTestCase2;
+import android.view.animation.AccelerateInterpolator;
public class ValueAnimatorTest extends
ActivityInstrumentationTestCase2<AnimationActivity> {
private AnimationActivity mActivity;
- private Instrumentation mInstrumentation;
private ValueAnimator mValueAnimator;
- private long mDuration;
+ private long mDuration = 1000;
public ValueAnimatorTest() {
- super("com.android.cts.animation",AnimationActivity.class);
- }
-
- public ValueAnimatorTest(Class<AnimationActivity> activityClass) {
- super("com.android.cts.animation",AnimationActivity.class);
+ super(AnimationActivity.class);
}
@Override
@@ -57,6 +55,16 @@
assertTrue(valueAnimatorReturned.isRunning());
}
+ public void testIsStarted() throws Throwable {
+ assertFalse(mValueAnimator.isRunning());
+ assertFalse(mValueAnimator.isStarted());
+ long startDelay = 10000;
+ mValueAnimator.setStartDelay(startDelay);
+ startAnimation(mValueAnimator);
+ assertFalse(mValueAnimator.isRunning());
+ assertTrue(mValueAnimator.isStarted());
+ }
+
public void testRepeatMode() throws Throwable {
ValueAnimator mValueAnimator = mActivity.createAnimatorWithRepeatMode(ValueAnimator.RESTART);
startAnimation(mValueAnimator);
@@ -92,12 +100,164 @@
assertEquals(frameDelay, actualFrameDelay);
}
- private void startAnimation(final ValueAnimator mValueAnimator) throws Throwable {
+ public void testSetInterpolator() throws Throwable {
+ AccelerateInterpolator interpolator = new AccelerateInterpolator();
+ ValueAnimator mValueAnimator = mActivity.createAnimatorWithInterpolator(interpolator);
+ startAnimation(mValueAnimator);
+ assertTrue(interpolator.equals(mValueAnimator.getInterpolator()));
+ }
+
+ public void testCancel() throws Throwable {
+ startAnimation(mValueAnimator);
+ Thread.sleep(100);
+ mValueAnimator.cancel();
+ assertFalse(mValueAnimator.isRunning());
+ }
+
+ public void testEnd() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ ObjectAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(new AccelerateInterpolator());
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ startAnimation(objAnimator);
+ Thread.sleep(100);
+ endAnimation(objAnimator);
+ float y = mActivity.view.newBall.getY();
+ assertEquals(y, endY);
+ }
+
+ public void testGetAnimatedFraction() throws Throwable {
+ ValueAnimator objAnimator = getAnimator();
+ startAnimation(objAnimator);
+ assertNotNull(objAnimator);
+ float[] fractions = getValue(objAnimator, 10, "getAnimatedFraction()", 100l, null);
+ for(int j = 0; j < 9; j++){
+ assertTrue(fractions[j] >= 0.0);
+ assertTrue(fractions[j] <= 1.0);
+ assertTrue(fractions[j + 1] != fractions[j]);
+ }
+ }
+
+ public void testGetAnimatedValue() throws Throwable {
+ ValueAnimator objAnimator = getAnimator();
+ startAnimation(objAnimator);
+ assertNotNull(objAnimator);
+ float[] animatedValues = getValue(objAnimator, 10, "getAnimatedValue()", 100l, null);
+
+ for(int j = 0; j < 9; j++){
+ assertTrue(animatedValues[j + 1] != animatedValues[j]);
+ }
+ }
+ public void testGetAnimatedValue_PropertyName() throws Throwable {
+ String property = "y";
+
+ ValueAnimator objAnimator = getAnimator();
+ startAnimation(objAnimator);
+ assertNotNull(objAnimator);
+ float[] animatedValues = getValue(objAnimator, 10, "getAnimatedValue(property)", 100l,
+ property);
+ for(int j = 0; j < 9; j++){
+ assertTrue(animatedValues[j + 1] != animatedValues[j]);
+ }
+ }
+
+ public void testOfFloat() throws Throwable {
+ float start = 0.0f;
+ float end = 1.0f;
+ float[] values = {start, end};
+ final ValueAnimator valueAnimatorLocal = ValueAnimator.ofFloat(values);
+ valueAnimatorLocal.setDuration(mDuration);
+ valueAnimatorLocal.setRepeatCount(ValueAnimator.INFINITE);
+ valueAnimatorLocal.setInterpolator(new AccelerateInterpolator());
+ valueAnimatorLocal.setRepeatMode(ValueAnimator.RESTART);
+
this.runTestOnUiThread(new Runnable(){
- public void run(){
- mActivity.startAnimation(mValueAnimator);
+ public void run() {
+ valueAnimatorLocal.start();
}
});
+ Thread.sleep(100);
+ boolean isRunning = valueAnimatorLocal.isRunning();
+ assertTrue(isRunning);
+
+ Float animatedValue = (Float) valueAnimatorLocal.getAnimatedValue();
+ assertTrue(animatedValue >= start);
+ assertTrue(animatedValue <= end);
+ }
+
+ public void testOfInt() throws Throwable {
+ int start = 0;
+ int end = 10;
+ int[] values = {start, end};
+ final ValueAnimator valueAnimatorLocal = ValueAnimator.ofInt(values);
+ valueAnimatorLocal.setDuration(mDuration);
+ valueAnimatorLocal.setRepeatCount(ValueAnimator.INFINITE);
+ valueAnimatorLocal.setInterpolator(new AccelerateInterpolator());
+ valueAnimatorLocal.setRepeatMode(ValueAnimator.RESTART);
+
+ this.runTestOnUiThread(new Runnable(){
+ public void run() {
+ valueAnimatorLocal.start();
+ }
+ });
+ Thread.sleep(100);
+ boolean isRunning = valueAnimatorLocal.isRunning();
+ assertTrue(isRunning);
+
+ Integer animatedValue = (Integer) valueAnimatorLocal.getAnimatedValue();
+ assertTrue(animatedValue >= start);
+ assertTrue(animatedValue <= end);
+ }
+
+ private ValueAnimator getAnimator() {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ ValueAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(new AccelerateInterpolator());
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ return objAnimator;
+ }
+
+ private float[] getValue(ValueAnimator animator, int n, String methodName,
+ long sleepTime, String property) throws InterruptedException {
+ float[] values = new float[n];
+ for(int i = 0; i < (n-1); i++){
+ Thread.sleep(sleepTime);
+ float value = 0.0f;
+ if(methodName.equals("getAnimatedFraction()")) {
+ value = animator.getAnimatedFraction();
+ }else if(methodName.equals("getAnimatedValue()")) {
+ value = ((Float)animator.getAnimatedValue()).floatValue();
+ }else if(methodName.equals("getAnimatedValue(property)")) {
+ value = ((Float)animator.getAnimatedValue(property)).floatValue();
+ }
+ values[i] = value;
+ }
+ return values;
+ }
+ private void startAnimation(final ValueAnimator mValueAnimator) throws Throwable {
+ this.runTestOnUiThread(new Runnable(){
+ public void run() {
+ mActivity.startAnimation(mValueAnimator);
+ }
+ });
+ }
+ private void endAnimation(final ValueAnimator mValueAnimator) throws Throwable {
+ Thread animationRunnable = new Thread() {
+ public void run() {
+ mValueAnimator.end();
+ }
+ };
+ this.runTestOnUiThread(animationRunnable);
}
}
diff --git a/tests/tests/openglperf/Android.mk b/tests/tests/openglperf/Android.mk
new file mode 100644
index 0000000..0663c73
--- /dev/null
+++ b/tests/tests/openglperf/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2011 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)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsOpenGlPerfTestCases
+
+# uncomment when dalvik.annotation.Test* are removed or part of SDK
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
diff --git a/tests/tests/openglperf/AndroidManifest.xml b/tests/tests/openglperf/AndroidManifest.xml
new file mode 100644
index 0000000..95a7cd1
--- /dev/null
+++ b/tests/tests/openglperf/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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="com.android.cts.openglperf"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+ <instrumentation
+ android:targetPackage="com.android.cts.openglperf"
+ android:name="android.test.InstrumentationTestRunner" />
+ <application
+ android:label="@string/app_name" >
+ <uses-library android:name="android.test.runner" />
+ <activity
+ android:name="android.openglperf.cts.GlPlanetsActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/tests/tests/openglperf/assets/world_512_512.jpg b/tests/tests/openglperf/assets/world_512_512.jpg
new file mode 100644
index 0000000..b92bfae
--- /dev/null
+++ b/tests/tests/openglperf/assets/world_512_512.jpg
Binary files differ
diff --git a/tests/tests/openglperf/res/values/strings.xml b/tests/tests/openglperf/res/values/strings.xml
new file mode 100644
index 0000000..2cdba7f
--- /dev/null
+++ b/tests/tests/openglperf/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<resources>
+ <string name="app_name">OpenGlPerfTest</string>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/GlPlanetsActivity.java b/tests/tests/openglperf/src/android/openglperf/cts/GlPlanetsActivity.java
new file mode 100644
index 0000000..5a8c0a8
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/GlPlanetsActivity.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2011 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.openglperf.cts;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Activity which runs GL test and measure FPS with given parameters passed from
+ * Intent. For the meaning of parameters, check {@PlanetsRenderingParam}
+ */
+public class GlPlanetsActivity extends Activity implements
+ RenderCompletionListener {
+ public static final String INTENT_EXTRA_NUM_PLANETS = "numPlanets";
+ public static final String INTENT_EXTRA_USE_VBO_VERTICES = "useVboVertices";
+ public static final String INTENT_EXTRA_USE_VBO_INDICES = "useVboIndiices";
+ public static final String INTENT_EXTRA_NUM_FRAMES = "numFrames";
+ public static final String INTENT_EXTRA_INDICES_PER_VERTEX = "numIndicesPerVertex";
+
+ public static final String INTENT_RESULT_FPS = "fps";
+ public static final String INTENT_RESULT_NUM_TRIANGLES = "numTrigngles";
+
+ private final Semaphore mSem = new Semaphore(0);
+ private float mFps;
+ private int mNumTriangles;
+
+ private PlanetsSurfaceView mView;
+
+ public boolean waitForGlPlanetsCompletionWithTimeout(long timeoutInSecs)
+ throws InterruptedException {
+ return mSem.tryAcquire(timeoutInSecs, TimeUnit.SECONDS);
+ }
+
+ public float getFps() {
+ return mFps;
+ }
+
+ public int getNumTriangles() {
+ return mNumTriangles;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ Intent intent = getIntent();
+ PlanetsRenderingParam param = new PlanetsRenderingParam();
+ param.mNumPlanets = intent.getIntExtra(INTENT_EXTRA_NUM_PLANETS, param.mNumPlanets);
+ param.mUseVboForVertices = intent.getBooleanExtra(INTENT_EXTRA_USE_VBO_VERTICES,
+ param.mUseVboForVertices);
+ param.mUseVboForIndices = intent.getBooleanExtra(INTENT_EXTRA_USE_VBO_INDICES,
+ param.mUseVboForIndices);
+ param.mNumFrames = intent.getIntExtra(INTENT_EXTRA_NUM_FRAMES, param.mNumFrames);
+ param.mNumIndicesPerVertex = intent.getIntExtra(INTENT_EXTRA_INDICES_PER_VERTEX,
+ param.mNumIndicesPerVertex);
+ mView = new PlanetsSurfaceView(this, param, this);
+ setContentView(mView);
+ }
+
+ @Override
+ public void onRenderCompletion(float fps, int numTriangles) {
+ mFps = fps;
+ mNumTriangles = numTriangles;
+ mSem.release();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/GlVboPerfTest.java b/tests/tests/openglperf/src/android/openglperf/cts/GlVboPerfTest.java
new file mode 100644
index 0000000..afd435c
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/GlVboPerfTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2011 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.openglperf.cts;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+public class GlVboPerfTest extends
+ ActivityInstrumentationTestCase2<GlPlanetsActivity> {
+ private static final String TAG = "GlVboPerfTest";
+ private static final int NUM_FRAMES_TO_RENDER = 100;
+ private static final long RENDERING_TIMEOUT = 5 * 60;
+ // 10% of fps_no_vbo is allowed to compensate variations in measurement
+ private static final float FPS_COMPARISON_MARGIN = 0.1f;
+ // the worst case should be above 70% of the best case
+ private static final float FPS_MIN_MAX_COMPARISON_PERCENTILE = 0.7f;
+
+ private float mFps;
+ private int mNumTriangles;
+
+ public GlVboPerfTest() {
+ super(GlPlanetsActivity.class);
+ }
+
+ public void testVboWithVaryingIndexBufferNumbers() throws Exception {
+ final int[] numIndexBuffers = {1, 10, 100, 200, 400}; // per vertex buffer
+ float[] fpsVbo = new float[numIndexBuffers.length];
+ float[] fpsNonVbo = new float[numIndexBuffers.length];
+
+ for (int i = 0; i < numIndexBuffers.length; i++) {
+ runRendering(0, true, true, numIndexBuffers[i]);
+ fpsVbo[i] = mFps;
+ runRendering(0, true, false, numIndexBuffers[i]);
+ fpsNonVbo[i] = mFps;
+ }
+ StringBuilder msgIndex = new StringBuilder();
+ StringBuilder msgVbo = new StringBuilder();
+ StringBuilder msgNonVbo = new StringBuilder();
+ msgIndex.append("index buffer ");
+ msgVbo.append("Vbo ");
+ msgNonVbo.append("Non-Vbo ");
+ for (int i = 0; i < numIndexBuffers.length; i++) {
+ msgIndex.append(numIndexBuffers[i]).append(" ");
+ msgVbo.append(fpsVbo[i]).append(" ");
+ msgNonVbo.append(fpsNonVbo[i]).append(" ");
+ }
+ Log.i(TAG, msgIndex.toString());
+ Log.i(TAG, msgVbo.toString());
+ Log.i(TAG, msgNonVbo.toString());
+
+ float[] minMaxVbo = findMinMax(fpsVbo);
+ float[] minMaxNonVbo = findMinMax(fpsNonVbo);
+
+ float delta = minMaxVbo[1] - (1f - FPS_COMPARISON_MARGIN)
+ * minMaxNonVbo[1];
+ assertTrue("VBO performance worse than non-VBO " + msgVbo + msgNonVbo, delta > 0f);
+ assertTrue(
+ "Too much FPS drop for VBO case " + msgVbo,
+ minMaxVbo[0] > (FPS_MIN_MAX_COMPARISON_PERCENTILE * minMaxVbo[1]));
+ assertTrue(
+ "Too much FPS drop for No VBO case " + msgNonVbo,
+ minMaxNonVbo[0] > (FPS_MIN_MAX_COMPARISON_PERCENTILE * minMaxNonVbo[1]));
+ }
+
+ public void testVboVsNonVboPerfGeometry0() throws Exception {
+ doRunVboVsNonVboPerfTest(0);
+ }
+
+ public void testVboVsNonVboPerfGeometry1() throws Exception {
+ doRunVboVsNonVboPerfTest(4);
+ }
+
+ private void runRendering(int numPlanets, boolean useVboVertex, boolean useVboIndex,
+ int indicesPerVertex) throws Exception {
+ Intent intent = new Intent();
+ intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_FRAMES,
+ NUM_FRAMES_TO_RENDER);
+ intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_PLANETS, numPlanets);
+ intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_USE_VBO_VERTICES, useVboVertex);
+ intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_USE_VBO_INDICES, useVboIndex);
+ intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_INDICES_PER_VERTEX, indicesPerVertex);
+
+ setActivityIntent(intent);
+ final GlPlanetsActivity activity = getActivity();
+ boolean waitResult = activity
+ .waitForGlPlanetsCompletionWithTimeout(RENDERING_TIMEOUT);
+ assertTrue("timeout while waiting for rendering completion", waitResult);
+
+ mFps = activity.getFps();
+ mNumTriangles = activity.getNumTriangles();
+
+ cleanUpActivity();
+ }
+
+ private void cleanUpActivity() throws Exception {
+ // finish the current activity and do clean-up so that a new activity
+ // can be launched in the same test run
+ super.tearDown();
+ super.setUp();
+ // wait until clean-up / set-up finishes
+ getInstrumentation().waitForIdleSync();
+ }
+
+ private void doRunVboVsNonVboPerfTest(int numPlanets) throws Exception {
+ runRendering(numPlanets, true, true, 1); // VBO
+ int numTrianglesVbo = mNumTriangles;
+ float fpsVbo = mFps;
+ runRendering(numPlanets, false, false, 1); // non-VBO
+
+ assertTrue("Number of triangles mismatch",
+ numTrianglesVbo == mNumTriangles);
+
+ // Margin amount of error is allowed due to measuring irregularity
+ float delta = fpsVbo - (1f - FPS_COMPARISON_MARGIN) * mFps;
+ StringBuilder testMsg = new StringBuilder();
+ testMsg.append("VBO performance worse than non-VBO ").append(fpsVbo).append(" ");
+ testMsg.append(mFps);
+ assertTrue(testMsg.toString(), delta > 0f);
+ }
+
+ private float[] findMinMax(float[] data) {
+ float min = data[0];
+ float max = data[0];
+
+ for (int i = 1; i < data.length; i++) {
+ if (data[i] > max) max = data[i];
+ if (data[i] < min) min = data[i];
+ }
+ float[] result = {min, max};
+ return result;
+ }
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderer.java b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderer.java
new file mode 100644
index 0000000..59a7782
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderer.java
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2011 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.openglperf.cts;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLUtils;
+import android.opengl.Matrix;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.System;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+
+public class PlanetsRenderer implements GLSurfaceView.Renderer {
+
+ private static final String TAG = "PlanetsRenderer";
+ // texture is from
+ // http://en.wikipedia.org/wiki/File:Mercator_projection_SW.jpg
+ private static final String TEXTURE_FILE = "world_512_512.jpg";
+
+ private final Context mContext;
+ private final PlanetsRenderingParam mParam;
+ private final RenderCompletionListener mListener;
+
+ private final Sphere[] mSpheres;
+ private final int mNumSpheres;
+ private final int mNumIndices;
+ private final int mVboVertices[];
+ private final int mVboIndices[];
+
+ // configurations for sun and planets
+ private static final int SPHERE_SLICES = 180;
+ private static final float RADIUS_SUN = 0.4f;
+ private static final float RADIUS_PLANET = 0.08f;
+ private static final float RADIUS_ORBIT = 0.9f;
+
+ private int mWidth;
+ private int mHeight;
+
+ private int mFrameCount = 0;
+ private static final int FPS_DISPLAY_INTERVAL = 50;
+ private long mLastFPSTime;
+ // for total FPS measurement
+ private long mRenderingStartTime;
+ private long mMeasurementStartTime;
+
+ private int mProgram; // shader program
+ private int mMVPMatrixHandle;
+ private float[] mMVPMatrix = new float[16];
+ private float[] mMMatrix = new float[16];
+ private float[] mVMatrix = new float[16];
+ private float[] mProjMatrix = new float[16];
+
+ private int mOffsetHandle;
+ private static final float[] mDefaultOffset = { 0f, 0f, 0f, 1f };
+ private int mPositionHandle;
+ private int mTexCoord0Handle;
+ private int mTextureHandle;
+ private int mTextureId;
+
+ /**
+ * @param numSlices
+ * complexity of sphere used. A sphere will have (numSlices + 1)
+ * x (numSlices x 1) much of vertices
+ * @param useVbo
+ * whether to use Vertex Buffer Object in rendering or not
+ * @param framesToGo
+ * number of frames to render before calling completion to
+ * listener
+ * @param listener
+ */
+ public PlanetsRenderer(Context context, PlanetsRenderingParam param,
+ RenderCompletionListener listener) {
+ resetTimer();
+ mContext = context;
+ mParam = param;
+ mNumSpheres = mParam.mNumPlanets + 1; // 1 for sun
+ mNumIndices = mNumSpheres * mParam.mNumIndicesPerVertex;
+ mSpheres = new Sphere[mNumSpheres];
+
+ printParams();
+
+ // for big model, this construction phase takes time...
+ mSpheres[0] = new Sphere(SPHERE_SLICES, 0f, 0f, 0f, RADIUS_SUN,
+ mParam.mNumIndicesPerVertex);
+ for (int i = 1; i < mNumSpheres; i++) {
+ mSpheres[i] = new Sphere(SPHERE_SLICES,
+ RADIUS_ORBIT * (float) Math.sin(((float) i) / (mNumSpheres - 1) * 2 * Math.PI),
+ RADIUS_ORBIT * (float) Math.cos(((float) i) / (mNumSpheres - 1) * 2 * Math.PI),
+ 0f, RADIUS_PLANET, mParam.mNumIndicesPerVertex);
+ }
+ mVboVertices = new int[mNumSpheres];
+ mVboIndices = new int[mNumIndices];
+ mListener = listener;
+ measureTime("construction");
+ }
+
+ public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
+ mProgram = createProgram(getVertexShader(), getFragmentShader());
+ if (mProgram == 0) {
+ // error, cannot proceed
+ throw new IllegalStateException("createProgram failed");
+ }
+ mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
+ mOffsetHandle = GLES20.glGetUniformLocation(mProgram, "uOffset");
+ mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
+ mTexCoord0Handle = GLES20.glGetAttribLocation(mProgram, "vTexCoord0");
+ mTextureHandle = GLES20.glGetUniformLocation(mProgram, "sTexture");
+
+ // Load the texture
+ mTextureId = createTexture2D();
+ }
+
+ public void onDrawFrame(GL10 glUnused) {
+ long currentTime = System.currentTimeMillis();
+
+ mFrameCount++;
+ if ((mFrameCount % FPS_DISPLAY_INTERVAL == 0) && (mFrameCount != 0)) {
+ float fps = (((float) FPS_DISPLAY_INTERVAL)
+ / ((float) (currentTime - mLastFPSTime)) * 1000.0f);
+ Log.i(TAG, "FPS " + fps);
+ mLastFPSTime = currentTime;
+ }
+
+ if ((mFrameCount == mParam.mNumFrames) && (mParam.mNumFrames > 0)) {
+ long timePassed = currentTime - mRenderingStartTime;
+ float fps = ((float) mParam.mNumFrames) / ((float) timePassed) * 1000.0f;
+ printGlInfos();
+ printParams();
+ int numTriangles = mNumSpheres * mSpheres[0].getTotalIndices() / 3;
+ Log.i(TAG, "Final FPS " + fps + " Num triangles " + numTriangles);
+ if (mListener != null) {
+ mListener.onRenderCompletion(fps, numTriangles);
+ return;
+ }
+ }
+
+ float angle = 0.090f * ((int) (currentTime % 4000L));
+ Matrix.setRotateM(mMMatrix, 0, angle, 0, 0, 1.0f);
+ Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
+ Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
+
+ GLES20.glUseProgram(mProgram);
+ GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
+
+ // Apply a ModelView Projection transformation
+ GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
+ GLES20.glUniform4f(mOffsetHandle, mDefaultOffset[0], mDefaultOffset[1],
+ mDefaultOffset[2], mDefaultOffset[3]);
+
+ GLES20.glEnableVertexAttribArray(mPositionHandle);
+ GLES20.glEnableVertexAttribArray(mTexCoord0Handle);
+
+ // Bind the texture
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureId);
+ // Set the sampler texture unit to 0
+ GLES20.glUniform1i(mTextureHandle, 0);
+
+ for (int i = 0; i < mNumSpheres; i++) {
+ if (mParam.mUseVboForVertices) {
+ // generating VBOs for each sphere is not efficient way for drawing
+ // multiple spheres
+ // But this is done for testing performance with big VBO buffers.
+ // So please do not copy this code as it is.
+ GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVboVertices[i]);
+ // Load the vertex position
+ GLES20.glVertexAttribPointer(mPositionHandle, 3,
+ GLES20.GL_FLOAT, false, mSpheres[i].getVeticesStride(),
+ 0);
+ // Load the texture coordinate
+ GLES20.glVertexAttribPointer(mTexCoord0Handle, 3,
+ GLES20.GL_FLOAT, false, mSpheres[i].getVeticesStride(),
+ 3 * Sphere.FLOAT_SIZE);
+ } else {
+ // Load the vertex position
+ GLES20.glVertexAttribPointer(mPositionHandle, 3,
+ GLES20.GL_FLOAT, false, mSpheres[i].getVeticesStride(),
+ mSpheres[i].getVertices());
+ // Load the texture coordinate
+ GLES20.glVertexAttribPointer(mTexCoord0Handle, 3,
+ GLES20.GL_FLOAT, false, mSpheres[i].getVeticesStride(),
+ mSpheres[i].getVertices().duplicate().position(3));
+ }
+ int[] numIndices = mSpheres[i].getNumIndices();
+ ShortBuffer[] indices = mSpheres[i].getIndices();
+ if (mParam.mUseVboForIndices) {
+ int indexVboBase = i * mParam.mNumIndicesPerVertex;
+ for (int j = 0; j < numIndices.length; j++) {
+ GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER,
+ mVboIndices[indexVboBase + j]);
+ GLES20.glDrawElements(GLES20.GL_TRIANGLES,
+ numIndices[j], GLES20.GL_UNSIGNED_SHORT,
+ 0);
+ }
+ } else {
+ for (int j = 0; j < numIndices.length; j++) {
+ GLES20.glDrawElements(GLES20.GL_TRIANGLES,
+ numIndices[j], GLES20.GL_UNSIGNED_SHORT,
+ indices[j]);
+ }
+ }
+ }
+ }
+
+ public void onSurfaceChanged(GL10 glUnused, int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ GLES20.glViewport(0, 0, width, height);
+ float ratio = (float) width / height;
+ Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
+ Matrix.setLookAtM(mVMatrix, 0, 0, 3, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+ createVbo();
+
+ // reset timer to remove delays added for FPS calculation.
+ mLastFPSTime = System.currentTimeMillis();
+ mRenderingStartTime = System.currentTimeMillis();
+ }
+
+ protected final String getVertexShader() {
+ // simple shader with MVP matrix and text coord
+ final String vShaderStr =
+ "uniform mat4 uMVPMatrix; \n"
+ + "uniform vec4 uOffset; \n"
+ + "attribute vec4 vPosition; \n"
+ + "attribute vec2 vTexCoord0; \n"
+ + "varying vec2 vTexCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_Position = uMVPMatrix * (vPosition + uOffset); \n"
+ + " vTexCoord = vTexCoord0; \n"
+ + "} \n";
+ return vShaderStr;
+ }
+
+ protected final String getFragmentShader() {
+ // simple shader with one texture for color
+ final String fShaderStr =
+ "precision mediump float; \n"
+ + "varying vec2 vTexCoord; \n"
+ + "uniform sampler2D sTexture; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_FragColor = texture2D( sTexture, vTexCoord );\n"
+ + "} \n";
+ return fShaderStr;
+ }
+
+ private int loadShader(int shaderType, String source) {
+ int shader = GLES20.glCreateShader(shaderType);
+ if (shader != 0) {
+ GLES20.glShaderSource(shader, source);
+ GLES20.glCompileShader(shader);
+ int[] compiled = new int[1];
+ GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
+ if (compiled[0] == 0) {
+ Log.e(TAG, "Could not compile shader " + shaderType + ":");
+ Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
+ GLES20.glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ return shader;
+ }
+
+ private int createProgram(String vertexSource, String fragmentSource) {
+ int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
+ if (vertexShader == 0) {
+ return 0;
+ }
+
+ int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
+ if (pixelShader == 0) {
+ return 0;
+ }
+
+ int program = GLES20.glCreateProgram();
+ if (program != 0) {
+ GLES20.glAttachShader(program, vertexShader);
+ checkGlError("glAttachShader");
+ GLES20.glAttachShader(program, pixelShader);
+ checkGlError("glAttachShader");
+ GLES20.glLinkProgram(program);
+ int[] linkStatus = new int[1];
+ GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
+ if (linkStatus[0] != GLES20.GL_TRUE) {
+ Log.e(TAG, "Could not link program: ");
+ Log.e(TAG, GLES20.glGetProgramInfoLog(program));
+ GLES20.glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ return program;
+ }
+
+ private int createTexture2D() {
+ // Texture object handle
+ int[] textureId = new int[1];
+
+ InputStream in = null;
+ try {
+ in = mContext.getAssets().open(TEXTURE_FILE);
+ Bitmap bitmap = BitmapFactory.decodeStream(in);
+
+ // Generate a texture object
+ GLES20.glGenTextures(1, textureId, 0);
+
+ // Bind the texture object
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId[0]);
+ GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
+
+ // Set the filtering mode
+ GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
+ GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
+ GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
+ GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
+
+ } catch (IOException e) {
+ throw new IllegalStateException("Couldn't load texture '" + TEXTURE_FILE
+ + "'", e);
+ } finally {
+ if (in != null)
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+
+ return textureId[0];
+ }
+
+ private void checkGlError(String op) {
+ int error;
+ while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+ Log.e(TAG, op + ": glError " + error);
+ throw new IllegalStateException(op + ": glError " + error);
+ }
+ }
+
+ private void createVbo() {
+ resetTimer();
+ if (mParam.mUseVboForVertices) {
+ GLES20.glGenBuffers(mNumSpheres, mVboVertices, 0);
+ checkGlError("glGenBuffers Vertex");
+ for (int i = 0; i < mNumSpheres; i++) {
+ GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVboVertices[i]);
+ FloatBuffer vertices = mSpheres[i].getVertices();
+ GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertices.limit()
+ * Sphere.FLOAT_SIZE, vertices, GLES20.GL_STATIC_DRAW);
+ checkGlError("glBufferData Vertex");
+ mSpheres[i].releaseVertexBuffer(); // release memory
+ }
+ }
+ if (mParam.mUseVboForIndices) {
+ GLES20.glGenBuffers(mNumIndices, mVboIndices, 0);
+ checkGlError("glGenBuffers Index");
+ for (int i = 0; i < mNumSpheres; i++) {
+ int[] numIndices = mSpheres[i].getNumIndices();
+ ShortBuffer[] indices = mSpheres[i].getIndices();
+ int indexVboBase = i * mParam.mNumIndicesPerVertex;
+ for (int j = 0; j < numIndices.length; j++) {
+ GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER,
+ mVboIndices[indexVboBase + j]);
+ GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER,
+ indices[j].limit() * Sphere.SHORT_SIZE, indices[j],
+ GLES20.GL_STATIC_DRAW);
+ checkGlError("glBufferData Index");
+
+ }
+ mSpheres[i].releaseIndexBuffer(); // release memory
+ }
+ }
+ GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
+ GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
+ measureTime("VBO creation");
+ }
+
+ private void resetTimer() {
+ mMeasurementStartTime = System.currentTimeMillis();
+ }
+
+ private void measureTime(String description) {
+ long currentTime = System.currentTimeMillis();
+ float timePassedInSecs = (float) (currentTime - mMeasurementStartTime) / 1000f;
+ Log.i(TAG, description + " time in secs: " + timePassedInSecs);
+ }
+
+ private void printGlInfos() {
+ Log.i(TAG, "Vendor " + GLES20.glGetString(GLES20.GL_VENDOR));
+ Log.i(TAG, "Version " + GLES20.glGetString(GLES20.GL_VERSION));
+ Log.i(TAG, "Renderer " + GLES20.glGetString(GLES20.GL_RENDERER));
+ Log.i(TAG, "Extensions " + GLES20.glGetString(GLES20.GL_EXTENSIONS));
+ }
+ private void printParams() {
+ Log.i(TAG, "UseVboForVertex " + mParam.mUseVboForVertices);
+ Log.i(TAG, "UseVboForIndex " + mParam.mUseVboForIndices);
+ Log.i(TAG, "No Spheres " + mNumSpheres);
+ Log.i(TAG, "No indices buffer per vertex " + mParam.mNumIndicesPerVertex);
+ }
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderingParam.java b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderingParam.java
new file mode 100644
index 0000000..5e2dfd0
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderingParam.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 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.openglperf.cts;
+
+public class PlanetsRenderingParam {
+ /** whether to use VBO for vertices data */
+ public boolean mUseVboForVertices = true;
+ /** whether to use VBO for indices data */
+ public boolean mUseVboForIndices = true;
+ /** number of indices buffer per one vertices buffer */
+ public int mNumIndicesPerVertex = 1;
+ /** number of planets to render. There is always a sun */
+ public int mNumPlanets = 0;
+ /** number of frames to render to calculate FPS and finish */
+ public int mNumFrames = 100;
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/PlanetsSurfaceView.java b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsSurfaceView.java
new file mode 100644
index 0000000..526f706
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsSurfaceView.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 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.openglperf.cts;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+
+class PlanetsSurfaceView extends GLSurfaceView {
+
+ public PlanetsSurfaceView(Context context, PlanetsRenderingParam param,
+ RenderCompletionListener listener) {
+ super(context);
+
+ setEGLContextClientVersion(2);
+ setRenderer(new PlanetsRenderer(context, param, listener));
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ setRenderMode(RENDERMODE_WHEN_DIRTY);
+ }
+
+ @Override
+ public void onResume() {
+ setRenderMode(RENDERMODE_CONTINUOUSLY);
+ super.onResume();
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/RenderCompletionListener.java b/tests/tests/openglperf/src/android/openglperf/cts/RenderCompletionListener.java
new file mode 100644
index 0000000..1643087
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/RenderCompletionListener.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011 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.openglperf.cts;
+
+public interface RenderCompletionListener {
+ /**
+ * @param fps total frame rate
+ * @param numTriangles Number of triangles in geometric model
+ */
+ void onRenderCompletion(float fps, int numTriangles);
+
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/Sphere.java b/tests/tests/openglperf/src/android/openglperf/cts/Sphere.java
new file mode 100644
index 0000000..e8876dd
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/Sphere.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2011 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.openglperf.cts;
+
+import java.lang.Math;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+/*
+ * Class for generating a sphere model for given input params
+ * The generated class will have vertices and indices
+ * Vertices data is composed of vertex coordinates in x, y, z followed by
+ * texture coordinates s, t for each vertex
+ * Indices store vertex indices for the whole sphere.
+ * Formula for generating sphere is originally coming from source code of
+ * OpenGL ES2.0 Programming guide
+ * which is available from http://code.google.com/p/opengles-book-samples/,
+ * but some changes were made to make texture look right.
+ */
+public class Sphere {
+ public static final int FLOAT_SIZE = 4;
+ public static final int SHORT_SIZE = 2;
+
+ private FloatBuffer mVertices;
+ private ShortBuffer[] mIndices;
+ private int[] mNumIndices;
+ private int mTotalIndices;
+
+ /*
+ * @param nSlices how many slice in horizontal direction.
+ * The same slice for vertical direction is applied.
+ * nSlices should be > 1 and should be <= 180
+ * @param x,y,z the origin of the sphere
+ * @param r the radius of the sphere
+ */
+ public Sphere(int nSlices, float x, float y, float z, float r, int indicesPerVertex) {
+
+ int iMax = nSlices + 1;
+ int nVertices = iMax * iMax;
+ if (nVertices > Short.MAX_VALUE) {
+ // this cannot be handled in one vertices / indices pair
+ throw new RuntimeException("nSlices " + nSlices + " too big for vertex");
+ }
+ mTotalIndices = nSlices * nSlices * 6;
+ float angleStepI = ((float) Math.PI / nSlices);
+ float angleStepJ = ((2.0f * (float) Math.PI) / nSlices);
+
+ // 3 vertex coords + 2 texture coords
+ mVertices = ByteBuffer.allocateDirect(nVertices * 5 * FLOAT_SIZE)
+ .order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mIndices = new ShortBuffer[indicesPerVertex];
+ mNumIndices = new int[indicesPerVertex];
+ // first evenly distribute to n-1 buffers, then put remaining ones to the last one.
+ int noIndicesPerBuffer = (mTotalIndices / indicesPerVertex / 6) * 6;
+ for (int i = 0; i < indicesPerVertex - 1; i++) {
+ mNumIndices[i] = noIndicesPerBuffer;
+ }
+ mNumIndices[indicesPerVertex - 1] = mTotalIndices - noIndicesPerBuffer *
+ (indicesPerVertex - 1);
+
+ for (int i = 0; i < indicesPerVertex; i++) {
+ mIndices[i] = ByteBuffer.allocateDirect(mNumIndices[i] * SHORT_SIZE)
+ .order(ByteOrder.nativeOrder()).asShortBuffer();
+ }
+ // calling put for each float took too much CPU time, so put by line instead
+ float[] vLineBuffer = new float[iMax * 5];
+ for (int i = 0; i < iMax; i++) {
+ for (int j = 0; j < iMax; j++) {
+ int vertexBase = j * 5;
+ float sini = (float) Math.sin(angleStepI * i);
+ float sinj = (float) Math.sin(angleStepJ * j);
+ float cosi = (float) Math.cos(angleStepI * i);
+ float cosj = (float) Math.cos(angleStepJ * j);
+ // vertex x,y,z
+ vLineBuffer[vertexBase + 0] = x + r * sini * sinj;
+ vLineBuffer[vertexBase + 1] = y + r * sini * cosj;
+ vLineBuffer[vertexBase + 2] = z + r * cosi;
+ // texture s,t
+ vLineBuffer[vertexBase + 3] = (float) j / (float) nSlices;
+ vLineBuffer[vertexBase + 4] = (1.0f - i) / (float)nSlices;
+ }
+ mVertices.put(vLineBuffer, 0, vLineBuffer.length);
+ }
+
+ short[] indexBuffer = new short[max(mNumIndices)];
+ int index = 0;
+ int bufferNum = 0;
+ for (int i = 0; i < nSlices; i++) {
+ for (int j = 0; j < nSlices; j++) {
+ int i1 = i + 1;
+ int j1 = j + 1;
+ if (index >= mNumIndices[bufferNum]) {
+ // buffer ready for moving to target
+ mIndices[bufferNum].put(indexBuffer, 0, mNumIndices[bufferNum]);
+ // move to the next one
+ index = 0;
+ bufferNum++;
+ }
+ indexBuffer[index++] = (short) (i * iMax + j);
+ indexBuffer[index++] = (short) (i1 * iMax + j);
+ indexBuffer[index++] = (short) (i1 * iMax + j1);
+ indexBuffer[index++] = (short) (i * iMax + j);
+ indexBuffer[index++] = (short) (i1 * iMax + j1);
+ indexBuffer[index++] = (short) (i * iMax + j1);
+ }
+ }
+ mIndices[bufferNum].put(indexBuffer, 0, mNumIndices[bufferNum]);
+
+ mVertices.position(0);
+ for (int i = 0; i < indicesPerVertex; i++) {
+ mIndices[i].position(0);
+ }
+ }
+
+ public FloatBuffer getVertices() {
+ return mVertices;
+ }
+
+ public int getVeticesStride() {
+ return 5*FLOAT_SIZE;
+ }
+
+ public ShortBuffer[] getIndices() {
+ return mIndices;
+ }
+
+ public int[] getNumIndices() {
+ return mNumIndices;
+ }
+
+ public int getTotalIndices() {
+ return mTotalIndices;
+ }
+ /** once VBO buffer is generated, model data can be dropped */
+ public void releaseVertexBuffer() {
+ mVertices = null;
+ }
+
+ public void releaseIndexBuffer() {
+ mVertices = null;
+ }
+
+ private int max(int[] array) {
+ int max = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] > max) max = array[i];
+ }
+ return max;
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberFormattingTextWatcherTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneNumberFormattingTextWatcherTest.java
deleted file mode 100644
index b96dcd9..0000000
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberFormattingTextWatcherTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2009 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.telephony.cts;
-
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-
-import android.telephony.PhoneNumberFormattingTextWatcher;
-import android.test.AndroidTestCase;
-import android.text.Editable;
-import android.widget.TextView;
-
-@TestTargetClass(PhoneNumberFormattingTextWatcher.class)
-public class PhoneNumberFormattingTextWatcherTest extends AndroidTestCase {
-
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "PhoneNumberFormattingTextWatcher",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.SUFFICIENT,
- method = "beforeTextChanged",
- args = {java.lang.CharSequence.class, int.class, int.class, int.class}
- ),
- @TestTargetNew(
- level = TestLevel.SUFFICIENT,
- method = "afterTextChanged",
- args = {android.text.Editable.class}
- ),
- @TestTargetNew(
- level = TestLevel.SUFFICIENT,
- method = "onTextChanged",
- args = {java.lang.CharSequence.class, int.class, int.class, int.class}
- )
- })
- public void testPhoneNumberFormattingTextWatcher() {
- TextView text = new TextView(getContext());
- text.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
-
- text.setText("+15551212");
- assertEquals("+1-555-1212", text.getText().toString());
-
- // delete first dash and first 5
- Editable edit = (Editable) text.getText();
- edit.delete(2, 3);
- assertEquals("+1-551-212", text.getText().toString());
-
- // already formatted correctly
- text.setText("+1-555-1212");
- assertEquals("+1-555-1212", text.getText().toString());
- }
-}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
index 41ee0dc..5768e6c 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
@@ -77,6 +77,10 @@
public void endElement(String uri, String localName, String name) throws SAXException {
super.endElement(uri, localName, name);
if ("constructor".equalsIgnoreCase(localName)) {
+ if (mCurrentParameterTypes.isEmpty()) {
+ // Don't add empty default constructors...
+ return;
+ }
ApiConstructor apiConstructor = new ApiConstructor(mCurrentClassName,
mCurrentParameterTypes);
ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
diff --git a/tools/cts-api-coverage/src/res/api-coverage.xsl b/tools/cts-api-coverage/src/res/api-coverage.xsl
index 91fe802..3743580 100644
--- a/tools/cts-api-coverage/src/res/api-coverage.xsl
+++ b/tools/cts-api-coverage/src/res/api-coverage.xsl
@@ -61,15 +61,15 @@
}
.red {
- background-color: #FF0000;
+ background-color: #FF6666;
}
.yellow {
- background-color: #FFFF00;
+ background-color: #FFFF66;
}
.green {
- background-color: #00FF00;
+ background-color: #66FF66;
}
</style>
</head>
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 3a07432..9eb26af 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -110,6 +110,7 @@
plan.Exclude('android\.core\.vm-tests')
plan.Exclude('android\.performance.*')
self.__WritePlan(plan, 'CTS')
+ self.__WritePlan(plan, 'CTS-TF')
plan.Exclude(r'android\.tests\.sigtest')
plan.Exclude(r'android\.core.*')