summaryrefslogtreecommitdiffstats
path: root/tests/src/com/android/gallery3d/ui
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src/com/android/gallery3d/ui')
-rw-r--r--tests/src/com/android/gallery3d/ui/GLCanvasStub.java160
-rw-r--r--tests/src/com/android/gallery3d/ui/GLRootMock.java50
-rw-r--r--tests/src/com/android/gallery3d/ui/GLRootStub.java41
-rw-r--r--tests/src/com/android/gallery3d/ui/GLViewMock.java87
-rw-r--r--tests/src/com/android/gallery3d/ui/GLViewTest.java398
-rw-r--r--tests/src/com/android/gallery3d/ui/PointerInfo.java222
6 files changed, 958 insertions, 0 deletions
diff --git a/tests/src/com/android/gallery3d/ui/GLCanvasStub.java b/tests/src/com/android/gallery3d/ui/GLCanvasStub.java
new file mode 100644
index 000000000..01f0350d2
--- /dev/null
+++ b/tests/src/com/android/gallery3d/ui/GLCanvasStub.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.RectF;
+
+import com.android.gallery3d.glrenderer.BasicTexture;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.GLId;
+import com.android.gallery3d.glrenderer.GLPaint;
+import com.android.gallery3d.glrenderer.RawTexture;
+
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+
+import javax.microedition.khronos.opengles.GL11;
+
+public class GLCanvasStub implements GLCanvas {
+ @Override
+ public void setSize(int width, int height) {}
+ @Override
+ public void clearBuffer() {}
+ @Override
+ public void clearBuffer(float[] argb) {}
+ public void setCurrentAnimationTimeMillis(long time) {}
+ public long currentAnimationTimeMillis() {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void setAlpha(float alpha) {}
+ @Override
+ public float getAlpha() {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void multiplyAlpha(float alpha) {}
+ @Override
+ public void translate(float x, float y, float z) {}
+ @Override
+ public void translate(float x, float y) {}
+ @Override
+ public void scale(float sx, float sy, float sz) {}
+ @Override
+ public void rotate(float angle, float x, float y, float z) {}
+ public boolean clipRect(int left, int top, int right, int bottom) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void save() {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void save(int saveFlags) {
+ throw new UnsupportedOperationException();
+ }
+ public void setBlendEnabled(boolean enabled) {}
+ @Override
+ public void restore() {}
+ @Override
+ public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint) {}
+ @Override
+ public void drawRect(float x1, float y1, float x2, float y2, GLPaint paint) {}
+ @Override
+ public void fillRect(float x, float y, float width, float height, int color) {}
+ @Override
+ public void drawTexture(
+ BasicTexture texture, int x, int y, int width, int height) {}
+ @Override
+ public void drawMesh(BasicTexture tex, int x, int y, int xyBuffer,
+ int uvBuffer, int indexBuffer, int indexCount) {}
+ public void drawTexture(BasicTexture texture,
+ int x, int y, int width, int height, float alpha) {}
+ @Override
+ public void drawTexture(BasicTexture texture, RectF source, RectF target) {}
+ @Override
+ public void drawTexture(BasicTexture texture, float[] mTextureTransform,
+ int x, int y, int w, int h) {}
+ public void drawMixed(BasicTexture from, BasicTexture to,
+ float ratio, int x, int y, int w, int h) {}
+ @Override
+ public void drawMixed(BasicTexture from, int to,
+ float ratio, int x, int y, int w, int h) {}
+ public void drawMixed(BasicTexture from, BasicTexture to,
+ float ratio, int x, int y, int width, int height, float alpha) {}
+ public BasicTexture copyTexture(int x, int y, int width, int height) {
+ throw new UnsupportedOperationException();
+ }
+ public GL11 getGLInstance() {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public boolean unloadTexture(BasicTexture texture) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void deleteBuffer(int bufferId) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void deleteRecycledResources() {}
+ @Override
+ public void multiplyMatrix(float[] mMatrix, int offset) {}
+ @Override
+ public void dumpStatisticsAndClear() {}
+ @Override
+ public void beginRenderTarget(RawTexture texture) {}
+ @Override
+ public void endRenderTarget() {}
+ @Override
+ public void drawMixed(BasicTexture from, int toColor,
+ float ratio, RectF src, RectF target) {}
+
+ @Override
+ public void setTextureParameters(BasicTexture texture) {
+ }
+ @Override
+ public void initializeTextureSize(BasicTexture texture, int format, int type) {
+ }
+ @Override
+ public void initializeTexture(BasicTexture texture, Bitmap bitmap) {
+ }
+ @Override
+ public void texSubImage2D(BasicTexture texture, int xOffset, int yOffset, Bitmap bitmap,
+ int format, int type) {
+ }
+ @Override
+ public int uploadBuffer(ByteBuffer buffer) {
+ return 0;
+ }
+ @Override
+ public int uploadBuffer(FloatBuffer buffer) {
+ return 0;
+ }
+ @Override
+ public void recoverFromLightCycle() {
+ }
+ @Override
+ public void getBounds(Rect bounds, int x, int y, int width, int height) {
+ }
+ @Override
+ public GLId getGLId() {
+ return null;
+ }
+}
diff --git a/tests/src/com/android/gallery3d/ui/GLRootMock.java b/tests/src/com/android/gallery3d/ui/GLRootMock.java
new file mode 100644
index 000000000..da78e14ec
--- /dev/null
+++ b/tests/src/com/android/gallery3d/ui/GLRootMock.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import com.android.gallery3d.anim.CanvasAnimation;
+
+public class GLRootMock implements GLRoot {
+ int mRequestRenderCalled;
+ int mRequestLayoutContentPaneCalled;
+
+ public void addOnGLIdleListener(OnGLIdleListener listener) {}
+ public void registerLaunchedAnimation(CanvasAnimation animation) {}
+ public void requestRenderForced() {
+ mRequestRenderCalled++;
+ }
+ public void requestRender() {
+ mRequestRenderCalled++;
+ }
+ public void requestLayoutContentPane() {
+ mRequestLayoutContentPaneCalled++;
+ }
+ public boolean hasStencil() { return true; }
+ public void lockRenderThread() {}
+ public void unlockRenderThread() {}
+ public void setContentPane(GLView content) {}
+ public void setOrientationSource(OrientationSource source) {}
+ public int getDisplayRotation() { return 0; }
+ public int getCompensation() { return 0; }
+ public Matrix getCompensationMatrix() { return null; }
+ public void freeze() {}
+ public void unfreeze() {}
+ public void setLightsOutMode(boolean enabled) {}
+ public Context getContext() { return null; }
+}
diff --git a/tests/src/com/android/gallery3d/ui/GLRootStub.java b/tests/src/com/android/gallery3d/ui/GLRootStub.java
new file mode 100644
index 000000000..25e7bca5b
--- /dev/null
+++ b/tests/src/com/android/gallery3d/ui/GLRootStub.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import com.android.gallery3d.anim.CanvasAnimation;
+
+public class GLRootStub implements GLRoot {
+ public void addOnGLIdleListener(OnGLIdleListener listener) {}
+ public void registerLaunchedAnimation(CanvasAnimation animation) {}
+ public void requestRenderForced() {}
+ public void requestRender() {}
+ public void requestLayoutContentPane() {}
+ public boolean hasStencil() { return true; }
+ public void lockRenderThread() {}
+ public void unlockRenderThread() {}
+ public void setContentPane(GLView content) {}
+ public void setOrientationSource(OrientationSource source) {}
+ public int getDisplayRotation() { return 0; }
+ public int getCompensation() { return 0; }
+ public Matrix getCompensationMatrix() { return null; }
+ public void freeze() {}
+ public void unfreeze() {}
+ public void setLightsOutMode(boolean enabled) {}
+ public Context getContext() { return null; }
+}
diff --git a/tests/src/com/android/gallery3d/ui/GLViewMock.java b/tests/src/com/android/gallery3d/ui/GLViewMock.java
new file mode 100644
index 000000000..9b7488f05
--- /dev/null
+++ b/tests/src/com/android/gallery3d/ui/GLViewMock.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.glrenderer.GLCanvas;
+
+class GLViewMock extends GLView {
+ // onAttachToRoot
+ int mOnAttachCalled;
+ GLRoot mRoot;
+ // onDetachFromRoot
+ int mOnDetachCalled;
+ // onVisibilityChanged
+ int mOnVisibilityChangedCalled;
+ // onLayout
+ int mOnLayoutCalled;
+ boolean mOnLayoutChangeSize;
+ // renderBackground
+ int mRenderBackgroundCalled;
+ // onMeasure
+ int mOnMeasureCalled;
+ int mOnMeasureWidthSpec;
+ int mOnMeasureHeightSpec;
+
+ @Override
+ public void onAttachToRoot(GLRoot root) {
+ mRoot = root;
+ mOnAttachCalled++;
+ super.onAttachToRoot(root);
+ }
+
+ @Override
+ public void onDetachFromRoot() {
+ mRoot = null;
+ mOnDetachCalled++;
+ super.onDetachFromRoot();
+ }
+
+ @Override
+ protected void onVisibilityChanged(int visibility) {
+ mOnVisibilityChangedCalled++;
+ }
+
+ @Override
+ protected void onLayout(boolean changeSize, int left, int top,
+ int right, int bottom) {
+ mOnLayoutCalled++;
+ mOnLayoutChangeSize = changeSize;
+ // call children's layout.
+ for (int i = 0, n = getComponentCount(); i < n; ++i) {
+ GLView item = getComponent(i);
+ item.layout(left, top, right, bottom);
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthSpec, int heightSpec) {
+ mOnMeasureCalled++;
+ mOnMeasureWidthSpec = widthSpec;
+ mOnMeasureHeightSpec = heightSpec;
+ // call children's measure.
+ for (int i = 0, n = getComponentCount(); i < n; ++i) {
+ GLView item = getComponent(i);
+ item.measure(widthSpec, heightSpec);
+ }
+ setMeasuredSize(widthSpec, heightSpec);
+ }
+
+ @Override
+ protected void renderBackground(GLCanvas view) {
+ mRenderBackgroundCalled++;
+ }
+}
diff --git a/tests/src/com/android/gallery3d/ui/GLViewTest.java b/tests/src/com/android/gallery3d/ui/GLViewTest.java
new file mode 100644
index 000000000..b17b25440
--- /dev/null
+++ b/tests/src/com/android/gallery3d/ui/GLViewTest.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.Rect;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.MotionEvent;
+
+import junit.framework.TestCase;
+
+@SmallTest
+public class GLViewTest extends TestCase {
+ @SuppressWarnings("unused")
+ private static final String TAG = "GLViewTest";
+
+ @SmallTest
+ public void testVisibility() {
+ GLViewMock a = new GLViewMock();
+ assertEquals(GLView.VISIBLE, a.getVisibility());
+ assertEquals(0, a.mOnVisibilityChangedCalled);
+ a.setVisibility(GLView.INVISIBLE);
+ assertEquals(GLView.INVISIBLE, a.getVisibility());
+ assertEquals(1, a.mOnVisibilityChangedCalled);
+ a.setVisibility(GLView.VISIBLE);
+ assertEquals(GLView.VISIBLE, a.getVisibility());
+ assertEquals(2, a.mOnVisibilityChangedCalled);
+ }
+
+ @SmallTest
+ public void testComponents() {
+ GLView view = new GLView();
+ assertEquals(0, view.getComponentCount());
+ try {
+ view.getComponent(0);
+ fail();
+ } catch (IndexOutOfBoundsException ex) {
+ // expected
+ }
+
+ GLView x = new GLView();
+ GLView y = new GLView();
+ view.addComponent(x);
+ view.addComponent(y);
+ assertEquals(2, view.getComponentCount());
+ assertSame(x, view.getComponent(0));
+ assertSame(y, view.getComponent(1));
+ view.removeComponent(x);
+ assertSame(y, view.getComponent(0));
+ try {
+ view.getComponent(1);
+ fail();
+ } catch (IndexOutOfBoundsException ex) {
+ // expected
+ }
+ try {
+ view.addComponent(y);
+ fail();
+ } catch (IllegalStateException ex) {
+ // expected
+ }
+ view.addComponent(x);
+ view.removeAllComponents();
+ assertEquals(0, view.getComponentCount());
+ }
+
+ @SmallTest
+ public void testBounds() {
+ GLView view = new GLView();
+
+ assertEquals(0, view.getWidth());
+ assertEquals(0, view.getHeight());
+
+ Rect b = view.bounds();
+ assertEquals(0, b.left);
+ assertEquals(0, b.top);
+ assertEquals(0, b.right);
+ assertEquals(0, b.bottom);
+
+ view.layout(10, 20, 30, 100);
+ assertEquals(20, view.getWidth());
+ assertEquals(80, view.getHeight());
+
+ b = view.bounds();
+ assertEquals(10, b.left);
+ assertEquals(20, b.top);
+ assertEquals(30, b.right);
+ assertEquals(100, b.bottom);
+ }
+
+ @SmallTest
+ public void testParent() {
+ GLView a = new GLView();
+ GLView b = new GLView();
+ assertNull(b.mParent);
+ a.addComponent(b);
+ assertSame(a, b.mParent);
+ a.removeComponent(b);
+ assertNull(b.mParent);
+ }
+
+ @SmallTest
+ public void testRoot() {
+ GLViewMock a = new GLViewMock();
+ GLViewMock b = new GLViewMock();
+ GLRoot r = new GLRootStub();
+ GLRoot r2 = new GLRootStub();
+ a.addComponent(b);
+
+ // Attach to root r
+ assertEquals(0, a.mOnAttachCalled);
+ assertEquals(0, b.mOnAttachCalled);
+ a.attachToRoot(r);
+ assertEquals(1, a.mOnAttachCalled);
+ assertEquals(1, b.mOnAttachCalled);
+ assertSame(r, a.getGLRoot());
+ assertSame(r, b.getGLRoot());
+
+ // Detach from r
+ assertEquals(0, a.mOnDetachCalled);
+ assertEquals(0, b.mOnDetachCalled);
+ a.detachFromRoot();
+ assertEquals(1, a.mOnDetachCalled);
+ assertEquals(1, b.mOnDetachCalled);
+
+ // Attach to another root r2
+ assertEquals(1, a.mOnAttachCalled);
+ assertEquals(1, b.mOnAttachCalled);
+ a.attachToRoot(r2);
+ assertEquals(2, a.mOnAttachCalled);
+ assertEquals(2, b.mOnAttachCalled);
+ assertSame(r2, a.getGLRoot());
+ assertSame(r2, b.getGLRoot());
+
+ // Detach from r2
+ assertEquals(1, a.mOnDetachCalled);
+ assertEquals(1, b.mOnDetachCalled);
+ a.detachFromRoot();
+ assertEquals(2, a.mOnDetachCalled);
+ assertEquals(2, b.mOnDetachCalled);
+ }
+
+ @SmallTest
+ public void testRoot2() {
+ GLView a = new GLViewMock();
+ GLViewMock b = new GLViewMock();
+ GLRoot r = new GLRootStub();
+
+ a.attachToRoot(r);
+
+ assertEquals(0, b.mOnAttachCalled);
+ a.addComponent(b);
+ assertEquals(1, b.mOnAttachCalled);
+
+ assertEquals(0, b.mOnDetachCalled);
+ a.removeComponent(b);
+ assertEquals(1, b.mOnDetachCalled);
+ }
+
+ @SmallTest
+ public void testInvalidate() {
+ GLView a = new GLView();
+ GLRootMock r = new GLRootMock();
+ a.attachToRoot(r);
+ assertEquals(0, r.mRequestRenderCalled);
+ a.invalidate();
+ assertEquals(1, r.mRequestRenderCalled);
+ }
+
+ @SmallTest
+ public void testRequestLayout() {
+ GLView a = new GLView();
+ GLView b = new GLView();
+ GLRootMock r = new GLRootMock();
+ a.attachToRoot(r);
+ a.addComponent(b);
+ assertEquals(0, r.mRequestLayoutContentPaneCalled);
+ b.requestLayout();
+ assertEquals(1, r.mRequestLayoutContentPaneCalled);
+ }
+
+ @SmallTest
+ public void testLayout() {
+ GLViewMock a = new GLViewMock();
+ GLViewMock b = new GLViewMock();
+ GLViewMock c = new GLViewMock();
+ GLRootMock r = new GLRootMock();
+
+ a.attachToRoot(r);
+ a.addComponent(b);
+ a.addComponent(c);
+
+ assertEquals(0, a.mOnLayoutCalled);
+ a.layout(10, 20, 60, 100);
+ assertEquals(1, a.mOnLayoutCalled);
+ assertEquals(1, b.mOnLayoutCalled);
+ assertEquals(1, c.mOnLayoutCalled);
+ assertTrue(a.mOnLayoutChangeSize);
+ assertTrue(b.mOnLayoutChangeSize);
+ assertTrue(c.mOnLayoutChangeSize);
+
+ // same size should not trigger onLayout
+ a.layout(10, 20, 60, 100);
+ assertEquals(1, a.mOnLayoutCalled);
+
+ // unless someone requested it, but only those on the path
+ // to the requester.
+ assertEquals(0, r.mRequestLayoutContentPaneCalled);
+ b.requestLayout();
+ a.layout(10, 20, 60, 100);
+ assertEquals(1, r.mRequestLayoutContentPaneCalled);
+ assertEquals(2, a.mOnLayoutCalled);
+ assertEquals(2, b.mOnLayoutCalled);
+ assertEquals(1, c.mOnLayoutCalled);
+ }
+
+ @SmallTest
+ public void testRender() {
+ GLViewMock a = new GLViewMock();
+ GLViewMock b = new GLViewMock();
+
+ a.addComponent(b);
+ GLCanvasStub canvas = new GLCanvasStub();
+ assertEquals(0, a.mRenderBackgroundCalled);
+ assertEquals(0, b.mRenderBackgroundCalled);
+ a.render(canvas);
+ assertEquals(1, a.mRenderBackgroundCalled);
+ assertEquals(1, b.mRenderBackgroundCalled);
+ }
+
+ @SmallTest
+ public void testMeasure() {
+ GLViewMock a = new GLViewMock();
+ GLViewMock b = new GLViewMock();
+ GLViewMock c = new GLViewMock();
+ GLRootMock r = new GLRootMock();
+
+ a.addComponent(b);
+ a.addComponent(c);
+ a.attachToRoot(r);
+
+ assertEquals(0, a.mOnMeasureCalled);
+ a.measure(100, 200);
+ assertEquals(1, a.mOnMeasureCalled);
+ assertEquals(1, b.mOnMeasureCalled);
+ assertEquals(100, a.mOnMeasureWidthSpec);
+ assertEquals(200, a.mOnMeasureHeightSpec);
+ assertEquals(100, b.mOnMeasureWidthSpec);
+ assertEquals(200, b.mOnMeasureHeightSpec);
+ assertEquals(100, a.getMeasuredWidth());
+ assertEquals(200, b.getMeasuredHeight());
+
+ // same spec should not trigger onMeasure
+ a.measure(100, 200);
+ assertEquals(1, a.mOnMeasureCalled);
+
+ // unless someone requested it, but only those on the path
+ // to the requester.
+ b.requestLayout();
+ a.measure(100, 200);
+ assertEquals(2, a.mOnMeasureCalled);
+ assertEquals(2, b.mOnMeasureCalled);
+ assertEquals(1, c.mOnMeasureCalled);
+ }
+
+ class MyGLView extends GLView {
+ private int mWidth;
+ int mOnTouchCalled;
+ int mOnTouchX;
+ int mOnTouchY;
+ int mOnTouchAction;
+
+ public MyGLView(int width) {
+ mWidth = width;
+ }
+
+ @Override
+ protected void onLayout(boolean changeSize, int left, int top,
+ int right, int bottom) {
+ // layout children from left to right
+ // call children's layout.
+ int x = 0;
+ for (int i = 0, n = getComponentCount(); i < n; ++i) {
+ GLView item = getComponent(i);
+ item.measure(0, 0);
+ int w = item.getMeasuredWidth();
+ int h = item.getMeasuredHeight();
+ item.layout(x, 0, x + w, h);
+ x += w;
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthSpec, int heightSpec) {
+ setMeasuredSize(mWidth, 100);
+ }
+
+ @Override
+ protected boolean onTouch(MotionEvent event) {
+ mOnTouchCalled++;
+ mOnTouchX = (int) event.getX();
+ mOnTouchY = (int) event.getY();
+ mOnTouchAction = event.getAction();
+ return true;
+ }
+ }
+
+ private MotionEvent NewMotionEvent(int action, int x, int y) {
+ return MotionEvent.obtain(0, 0, action, x, y, 0);
+ }
+
+ @SmallTest
+ public void testTouchEvent() {
+ // We construct a tree with four nodes. Only the x coordinate is used:
+ // A = [0..............................300)
+ // B = [0......100)
+ // C = [100......200)
+ // D = [100..150)
+
+ MyGLView a = new MyGLView(300);
+ MyGLView b = new MyGLView(100);
+ MyGLView c = new MyGLView(100);
+ MyGLView d = new MyGLView(50);
+ GLRoot r = new GLRootStub();
+
+ a.addComponent(b);
+ a.addComponent(c);
+ c.addComponent(d);
+ a.attachToRoot(r);
+ a.layout(0, 0, 300, 100);
+
+ int DOWN = MotionEvent.ACTION_DOWN;
+ int UP = MotionEvent.ACTION_UP;
+ int MOVE = MotionEvent.ACTION_MOVE;
+ int CANCEL = MotionEvent.ACTION_CANCEL;
+
+ // simple case
+ assertEquals(0, a.mOnTouchCalled);
+ a.dispatchTouchEvent(NewMotionEvent(DOWN, 250, 0));
+ assertEquals(DOWN, a.mOnTouchAction);
+ a.dispatchTouchEvent(NewMotionEvent(UP, 250, 0));
+ assertEquals(UP, a.mOnTouchAction);
+ assertEquals(2, a.mOnTouchCalled);
+
+ // pass to a child, check the location is offseted.
+ assertEquals(0, c.mOnTouchCalled);
+ a.dispatchTouchEvent(NewMotionEvent(DOWN, 175, 0));
+ a.dispatchTouchEvent(NewMotionEvent(UP, 175, 0));
+ assertEquals(75, c.mOnTouchX);
+ assertEquals(0, c.mOnTouchY);
+ assertEquals(2, c.mOnTouchCalled);
+ assertEquals(2, a.mOnTouchCalled);
+
+ // motion target cancel event
+ assertEquals(0, d.mOnTouchCalled);
+ a.dispatchTouchEvent(NewMotionEvent(DOWN, 125, 0));
+ assertEquals(1, d.mOnTouchCalled);
+ a.dispatchTouchEvent(NewMotionEvent(MOVE, 250, 0));
+ assertEquals(2, d.mOnTouchCalled);
+ a.dispatchTouchEvent(NewMotionEvent(MOVE, 50, 0));
+ assertEquals(3, d.mOnTouchCalled);
+ a.dispatchTouchEvent(NewMotionEvent(DOWN, 175, 0));
+ assertEquals(4, d.mOnTouchCalled);
+ assertEquals(CANCEL, d.mOnTouchAction);
+ assertEquals(3, c.mOnTouchCalled);
+ assertEquals(DOWN, c.mOnTouchAction);
+ a.dispatchTouchEvent(NewMotionEvent(UP, 175, 0));
+
+ // motion target is removed
+ assertEquals(4, d.mOnTouchCalled);
+ a.dispatchTouchEvent(NewMotionEvent(DOWN, 125, 0));
+ assertEquals(5, d.mOnTouchCalled);
+ a.removeComponent(c);
+ assertEquals(6, d.mOnTouchCalled);
+ assertEquals(CANCEL, d.mOnTouchAction);
+
+ // invisible component should not get events
+ assertEquals(2, a.mOnTouchCalled);
+ assertEquals(0, b.mOnTouchCalled);
+ b.setVisibility(GLView.INVISIBLE);
+ a.dispatchTouchEvent(NewMotionEvent(DOWN, 50, 0));
+ assertEquals(3, a.mOnTouchCalled);
+ assertEquals(0, b.mOnTouchCalled);
+ }
+}
diff --git a/tests/src/com/android/gallery3d/ui/PointerInfo.java b/tests/src/com/android/gallery3d/ui/PointerInfo.java
new file mode 100644
index 000000000..6c78556e1
--- /dev/null
+++ b/tests/src/com/android/gallery3d/ui/PointerInfo.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.opengles.GL10;
+
+public class PointerInfo {
+
+ /**
+ * The number of coordinates per vertex. 1..4
+ */
+ public int mSize;
+
+ /**
+ * The type of each coordinate.
+ */
+ public int mType;
+
+ /**
+ * The byte offset between consecutive vertices. 0 means mSize *
+ * sizeof(mType)
+ */
+ public int mStride;
+ public Buffer mPointer;
+ public ByteBuffer mTempByteBuffer;
+
+ public PointerInfo(int size, int type, int stride, Buffer pointer) {
+ mSize = size;
+ mType = type;
+ mStride = stride;
+ mPointer = pointer;
+ }
+
+ private int getStride() {
+ return mStride > 0 ? mStride : sizeof(mType) * mSize;
+ }
+
+ public void bindByteBuffer() {
+ mTempByteBuffer = mPointer == null ? null : toByteBuffer(-1, mPointer);
+ }
+
+ public void unbindByteBuffer() {
+ mTempByteBuffer = null;
+ }
+
+ private static int sizeof(int type) {
+ switch (type) {
+ case GL10.GL_UNSIGNED_BYTE:
+ return 1;
+ case GL10.GL_BYTE:
+ return 1;
+ case GL10.GL_SHORT:
+ return 2;
+ case GL10.GL_FIXED:
+ return 4;
+ case GL10.GL_FLOAT:
+ return 4;
+ default:
+ return 0;
+ }
+ }
+
+ private static ByteBuffer toByteBuffer(int byteCount, Buffer input) {
+ ByteBuffer result = null;
+ boolean convertWholeBuffer = (byteCount < 0);
+ if (input instanceof ByteBuffer) {
+ ByteBuffer input2 = (ByteBuffer) input;
+ int position = input2.position();
+ if (convertWholeBuffer) {
+ byteCount = input2.limit() - position;
+ }
+ result = ByteBuffer.allocate(byteCount).order(input2.order());
+ for (int i = 0; i < byteCount; i++) {
+ result.put(input2.get());
+ }
+ input2.position(position);
+ } else if (input instanceof CharBuffer) {
+ CharBuffer input2 = (CharBuffer) input;
+ int position = input2.position();
+ if (convertWholeBuffer) {
+ byteCount = (input2.limit() - position) * 2;
+ }
+ result = ByteBuffer.allocate(byteCount).order(input2.order());
+ CharBuffer result2 = result.asCharBuffer();
+ for (int i = 0; i < byteCount / 2; i++) {
+ result2.put(input2.get());
+ }
+ input2.position(position);
+ } else if (input instanceof ShortBuffer) {
+ ShortBuffer input2 = (ShortBuffer) input;
+ int position = input2.position();
+ if (convertWholeBuffer) {
+ byteCount = (input2.limit() - position)* 2;
+ }
+ result = ByteBuffer.allocate(byteCount).order(input2.order());
+ ShortBuffer result2 = result.asShortBuffer();
+ for (int i = 0; i < byteCount / 2; i++) {
+ result2.put(input2.get());
+ }
+ input2.position(position);
+ } else if (input instanceof IntBuffer) {
+ IntBuffer input2 = (IntBuffer) input;
+ int position = input2.position();
+ if (convertWholeBuffer) {
+ byteCount = (input2.limit() - position) * 4;
+ }
+ result = ByteBuffer.allocate(byteCount).order(input2.order());
+ IntBuffer result2 = result.asIntBuffer();
+ for (int i = 0; i < byteCount / 4; i++) {
+ result2.put(input2.get());
+ }
+ input2.position(position);
+ } else if (input instanceof FloatBuffer) {
+ FloatBuffer input2 = (FloatBuffer) input;
+ int position = input2.position();
+ if (convertWholeBuffer) {
+ byteCount = (input2.limit() - position) * 4;
+ }
+ result = ByteBuffer.allocate(byteCount).order(input2.order());
+ FloatBuffer result2 = result.asFloatBuffer();
+ for (int i = 0; i < byteCount / 4; i++) {
+ result2.put(input2.get());
+ }
+ input2.position(position);
+ } else if (input instanceof DoubleBuffer) {
+ DoubleBuffer input2 = (DoubleBuffer) input;
+ int position = input2.position();
+ if (convertWholeBuffer) {
+ byteCount = (input2.limit() - position) * 8;
+ }
+ result = ByteBuffer.allocate(byteCount).order(input2.order());
+ DoubleBuffer result2 = result.asDoubleBuffer();
+ for (int i = 0; i < byteCount / 8; i++) {
+ result2.put(input2.get());
+ }
+ input2.position(position);
+ } else if (input instanceof LongBuffer) {
+ LongBuffer input2 = (LongBuffer) input;
+ int position = input2.position();
+ if (convertWholeBuffer) {
+ byteCount = (input2.limit() - position) * 8;
+ }
+ result = ByteBuffer.allocate(byteCount).order(input2.order());
+ LongBuffer result2 = result.asLongBuffer();
+ for (int i = 0; i < byteCount / 8; i++) {
+ result2.put(input2.get());
+ }
+ input2.position(position);
+ } else {
+ throw new RuntimeException("Unimplemented Buffer subclass.");
+ }
+ result.rewind();
+ // The OpenGL API will interpret the result in hardware byte order,
+ // so we better do that as well:
+ result.order(ByteOrder.nativeOrder());
+ return result;
+ }
+
+ public void getArrayElement(int index, double[] result) {
+ if (mTempByteBuffer == null) {
+ throw new IllegalArgumentException("undefined pointer");
+ }
+ if (mStride < 0) {
+ throw new IllegalArgumentException("invalid stride");
+ }
+
+ int stride = getStride();
+ ByteBuffer byteBuffer = mTempByteBuffer;
+ int size = mSize;
+ int type = mType;
+ int sizeofType = sizeof(type);
+ int byteOffset = stride * index;
+
+ for (int i = 0; i < size; i++) {
+ switch (type) {
+ case GL10.GL_BYTE:
+ case GL10.GL_UNSIGNED_BYTE:
+ result[i] = byteBuffer.get(byteOffset);
+ break;
+ case GL10.GL_SHORT:
+ ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
+ result[i] = shortBuffer.get(byteOffset / 2);
+ break;
+ case GL10.GL_FIXED:
+ IntBuffer intBuffer = byteBuffer.asIntBuffer();
+ result[i] = intBuffer.get(byteOffset / 4);
+ break;
+ case GL10.GL_FLOAT:
+ FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
+ result[i] = floatBuffer.get(byteOffset / 4);
+ break;
+ default:
+ throw new UnsupportedOperationException("unknown type");
+ }
+ byteOffset += sizeofType;
+ }
+ }
+}