blob: b17b254407e8c3e81813b11befa41efd0a3b3b62 [file] [log] [blame]
/*
* 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);
}
}