blob: b58be6286a84b27c34270d023c392de07a0d517a [file] [log] [blame]
/*
* Copyright (C) 2008 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.widget.cts;
import com.android.cts.stub.R;
import com.android.internal.view.menu.ContextMenuBuilder;
import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import dalvik.annotation.ToBeFixed;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.test.TouchUtils;
import android.test.UiThreadTest;
import android.test.ViewAsserts;
import android.util.AttributeSet;
import android.util.Xml;
import android.view.ContextMenu;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Transformation;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.AdapterView.OnItemSelectedListener;
import java.io.IOException;
/**
* Test {@link Gallery}.
*/
@TestTargetClass(Gallery.class)
public class GalleryTest extends ActivityInstrumentationTestCase2<GalleryStubActivity> {
private Gallery mGallery;
private Activity mActivity;
private Instrumentation mInstrumentation;
private Context mContext;
private final static float DELTA = 0.01f;
public GalleryTest() {
super("com.android.cts.stub", GalleryStubActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
mActivity = getActivity();
mInstrumentation = getInstrumentation();
mContext = mInstrumentation.getContext();
mGallery = (Gallery) mActivity.findViewById(R.id.gallery_test);
}
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "Gallery",
args = {android.content.Context.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "Gallery",
args = {android.content.Context.class, android.util.AttributeSet.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "Gallery",
args = {android.content.Context.class, android.util.AttributeSet.class, int.class}
)
})
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete")
public void testConstructor() {
new Gallery(mContext);
new Gallery(mContext, null);
new Gallery(mContext, null, 0);
XmlPullParser parser = getActivity().getResources().getXml(R.layout.gallery_test);
AttributeSet attrs = Xml.asAttributeSet(parser);
new Gallery(mContext, attrs);
new Gallery(mContext, attrs, 0);
try {
new Gallery(null);
fail("should throw NullPointerException.");
} catch (NullPointerException e) {
// expected
}
try {
new Gallery(null, null);
fail("should throw NullPointerException.");
} catch (NullPointerException e) {
// expected
}
try {
new Gallery(null, null, 0);
fail("should throw NullPointerException.");
} catch (NullPointerException e) {
// expected
}
}
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setCallbackDuringFling",
args = {boolean.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "onTouchEvent",
args = {android.view.MotionEvent.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "onFling",
args = {MotionEvent.class, MotionEvent.class, float.class, float.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "onDown",
args = {android.view.MotionEvent.class}
)
})
@BrokenTest("listener.isItemSelected() is false, need to investigate")
public void testSetCallbackDuringFling() {
MockOnItemSelectedListener listener = new MockOnItemSelectedListener();
mGallery.setOnItemSelectedListener(listener);
mGallery.setCallbackDuringFling(true);
int[] xy = new int[2];
getSelectedViewCenter(mGallery, xy);
// This drags over only one item.
TouchUtils.drag(this, xy[0], 0, xy[1], xy[1], 1);
listener.reset();
// This will drags over several items.
TouchUtils.drag(this, xy[0], 0, xy[1], xy[1], 1);
assertTrue(listener.isItemSelected());
// onItemSelected called more than once
assertTrue(listener.getItemSelectedCalledCount() > 1);
listener.reset();
mGallery.setCallbackDuringFling(false);
TouchUtils.drag(this, xy[0], 240, xy[1], xy[1], 1);
assertTrue(listener.isItemSelected());
// onItemSelected called only once
assertTrue(listener.getItemSelectedCalledCount() == 1);
}
private void getSelectedViewCenter(Gallery gallery, int[] xy) {
View v = gallery.getSelectedView();
v.getLocationOnScreen(xy);
final int viewWidth = v.getWidth();
final int viewHeight = v.getHeight();
xy[1] += viewHeight / 2;
xy[0] += viewWidth / 2;
}
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
method = "setAnimationDuration",
args = {int.class}
)
@ToBeFixed(bug = "1386429", explanation = "No getter and can't check indirectly. "
+ "It is hard to get transition animation to check if the duration is right.")
public void testSetAnimationDuration() {
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setSpacing",
args = {int.class}
)
public void testSetSpacing() throws Throwable {
setSpacingAndCheck(0);
setSpacingAndCheck(5);
setSpacingAndCheck(-1);
}
private void setSpacingAndCheck(final int spacing) throws Throwable {
runTestOnUiThread(new Runnable() {
public void run() {
mGallery.setSpacing(spacing);
mGallery.requestLayout();
}
});
mInstrumentation.waitForIdleSync();
View v0 = mGallery.getChildAt(0);
View v1 = mGallery.getChildAt(1);
assertEquals(v0.getRight() + spacing, v1.getLeft());
}
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setUnselectedAlpha",
args = {float.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getChildStaticTransformation",
args = {android.view.View.class, android.view.animation.Transformation.class}
)
})
public void testSetUnselectedAlpha() {
final MyGallery gallery = (MyGallery) mActivity.findViewById(R.id.gallery_test);
checkUnselectedAlpha(gallery, 0.0f);
checkUnselectedAlpha(gallery, 0.5f);
}
private void checkUnselectedAlpha(MyGallery gallery, float alpha) {
final float DEFAULT_ALPHA = 1.0f;
View v0 = gallery.getChildAt(0);
View v1 = gallery.getChildAt(1);
gallery.setUnselectedAlpha(alpha);
Transformation t = new Transformation();
gallery.getChildStaticTransformation(v0, t);
// v0 is selected by default.
assertEquals(DEFAULT_ALPHA, t.getAlpha(), DELTA);
gallery.getChildStaticTransformation(v1, t);
assertEquals(alpha, t.getAlpha(), DELTA);
}
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "generateLayoutParams",
args = {android.util.AttributeSet.class}
),
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "generateLayoutParams",
args = {android.view.ViewGroup.LayoutParams.class}
)
})
public void testGenerateLayoutParams() throws XmlPullParserException, IOException {
final int width = 320;
final int height = 240;
LayoutParams lp = new LayoutParams(width, height);
MyGallery gallery = new MyGallery(mContext);
LayoutParams layoutParams = gallery.generateLayoutParams(lp);
assertEquals(width, layoutParams.width);
assertEquals(height, layoutParams.height);
XmlPullParser parser = getActivity().getResources().getXml(R.layout.gallery_test);
WidgetTestUtils.beginDocument(parser, "LinearLayout");
AttributeSet attrs = Xml.asAttributeSet(parser);
mGallery = new Gallery(mContext, attrs);
layoutParams = mGallery.generateLayoutParams(attrs);
assertEquals(LayoutParams.FILL_PARENT, layoutParams.width);
assertEquals(LayoutParams.FILL_PARENT, layoutParams.height);
}
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "onSingleTapUp",
args = {MotionEvent.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "onScroll",
args = {MotionEvent.class, MotionEvent.class, float.class, float.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "onLongPress",
args = {android.view.MotionEvent.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "onShowPress",
args = {android.view.MotionEvent.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "onKeyDown",
args = {int.class, android.view.KeyEvent.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "onKeyUp",
args = {int.class, android.view.KeyEvent.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "onFocusChanged",
args = {boolean.class, int.class, android.graphics.Rect.class}
),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
method = "onLayout",
args = {boolean.class, int.class, int.class, int.class, int.class}
)
})
public void testFoo() {
// Do not test these APIs. They are callbacks which:
// 1. The callback machanism has been tested in super class
// 2. The functionality is implmentation details, no need to test
}
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
method = "dispatchSetSelected",
args = {boolean.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are not right, "
+ "dispatchSetSelected() does not dispatch setSelected to all child views.")
public void testDispatchSetSelected() {
int count = mGallery.getChildCount();
mGallery.dispatchSetSelected(false);
for (int i = 0; i < count; i++) {
// the child view should not be selected, but a item still is selected.
if (i == mGallery.getSelectedItemPosition()) {
assertTrue(mGallery.getChildAt(i).isSelected());
} else {
assertFalse(mGallery.getChildAt(i).isSelected());
}
}
mGallery.dispatchSetSelected(true);
for (int i = 0; i < count; i++) {
// the child view should be selected, but some items still are selected.
if (i == mGallery.getSelectedItemPosition()) {
assertTrue(mGallery.getChildAt(i).isSelected());
} else {
assertFalse(mGallery.getChildAt(i).isSelected());
}
}
}
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
method = "showContextMenuForChild",
args = {android.view.View.class}
)
public void testShowContextMenuForChild() {
// how to check whether the context menu for child is showing.
}
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
method = "showContextMenu",
args = {}
)
public void testShowContextMenu() {
// how to check whether the context menu is showing.
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "dispatchKeyEvent",
args = {android.view.KeyEvent.class}
)
public void testDispatchKeyEvent() {
mGallery = new Gallery(mContext);
final KeyEvent validKeyEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER);
assertTrue(mGallery.dispatchKeyEvent(validKeyEvent));
final long time = SystemClock.uptimeMillis();
final KeyEvent invalidKeyEvent
= new KeyEvent(time, time, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A, 5);
assertFalse(mGallery.dispatchKeyEvent(invalidKeyEvent));
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setGravity",
args = {int.class}
)
public void testSetGravity() throws Throwable {
setGalleryGravity(Gravity.CENTER_HORIZONTAL);
View v0 = mGallery.getChildAt(0);
ViewAsserts.assertHorizontalCenterAligned(mGallery, v0);
setGalleryGravity(Gravity.TOP);
v0 = mGallery.getChildAt(0);
ViewAsserts.assertTopAligned(mGallery, v0, mGallery.getPaddingTop());
setGalleryGravity(Gravity.BOTTOM);
v0 = mGallery.getChildAt(0);
ViewAsserts.assertBottomAligned(mGallery, v0, mGallery.getPaddingBottom());
}
private void setGalleryGravity(final int gravity) throws Throwable {
runTestOnUiThread(new Runnable() {
public void run() {
mGallery.setGravity(gravity);
mGallery.invalidate();
mGallery.requestLayout();
}
});
mInstrumentation.waitForIdleSync();
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "checkLayoutParams",
args = {android.view.ViewGroup.LayoutParams.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete")
public void testCheckLayoutParams() {
MyGallery gallery = new MyGallery(mContext);
ViewGroup.LayoutParams p1 = new ViewGroup.LayoutParams(320, 480);
assertFalse(gallery.checkLayoutParams(p1));
Gallery.LayoutParams p2 = new Gallery.LayoutParams(320, 480);
assertTrue(gallery.checkLayoutParams(p2));
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "computeHorizontalScrollExtent",
args = {}
)
public void testComputeHorizontalScrollExtent() {
MyGallery gallery = new MyGallery(mContext);
// only one item is considered to be selected.
assertEquals(1, gallery.computeHorizontalScrollExtent());
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "computeHorizontalScrollOffset",
args = {}
)
public void testComputeHorizontalScrollOffset() {
MyGallery gallery = new MyGallery(mContext);
assertEquals(AdapterView.INVALID_POSITION, gallery.computeHorizontalScrollOffset());
gallery.setAdapter(new ImageAdapter(mActivity));
// Current scroll position is the same as the selected position
assertEquals(gallery.getSelectedItemPosition(), gallery.computeHorizontalScrollOffset());
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "computeHorizontalScrollRange",
args = {}
)
public void testComputeHorizontalScrollRange() {
MyGallery gallery = new MyGallery(mContext);
ImageAdapter adapter = new ImageAdapter(mActivity);
gallery.setAdapter(adapter);
// Scroll range is the same as the item count
assertEquals(adapter.getCount(), gallery.computeHorizontalScrollRange());
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "dispatchSetPressed",
args = {boolean.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are not right, "
+ "dispatchSetPressed did not dispatch setPressed to "
+ "all of this View's children, but only the selected view")
@UiThreadTest
public void testDispatchSetPressed() {
final MyGallery gallery = (MyGallery) getActivity().findViewById(R.id.gallery_test);
gallery.setSelection(0);
gallery.dispatchSetPressed(true);
assertTrue(gallery.getSelectedView().isPressed());
assertFalse(gallery.getChildAt(1).isPressed());
gallery.dispatchSetPressed(false);
assertFalse(gallery.getSelectedView().isPressed());
assertFalse(gallery.getChildAt(1).isPressed());
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "generateDefaultLayoutParams",
args = {}
)
public void testGenerateDefaultLayoutParams() {
MyGallery gallery = new MyGallery(mContext);
ViewGroup.LayoutParams p = gallery.generateDefaultLayoutParams();
assertNotNull(p);
assertTrue(p instanceof Gallery.LayoutParams);
assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, p.width);
assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, p.height);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getChildDrawingOrder",
args = {int.class, int.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete")
public void testGetChildDrawingOrder() {
final MyGallery gallery = (MyGallery) getActivity().findViewById(R.id.gallery_test);
int childCount = 3;
int index = 2;
assertEquals(gallery.getSelectedItemPosition(),
gallery.getChildDrawingOrder(childCount, index));
childCount = 5;
index = 2;
assertEquals(index + 1, gallery.getChildDrawingOrder(childCount, index));
childCount = 5;
index = 3;
assertEquals(index + 1, gallery.getChildDrawingOrder(childCount, index));
}
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getContextMenuInfo",
args = {}
)
public void testGetContextMenuInfo() {
MockOnCreateContextMenuListener listener = new MockOnCreateContextMenuListener();
MyGallery gallery = new MyGallery(mContext);
gallery.setOnCreateContextMenuListener(listener);
assertFalse(listener.hasCreatedContextMenu());
gallery.createContextMenu(new ContextMenuBuilder(mContext));
assertTrue(listener.hasCreatedContextMenu());
assertSame(gallery.getContextMenuInfo(), listener.getContextMenuInfo());
}
private static class MockOnCreateContextMenuListener implements OnCreateContextMenuListener {
private boolean hasCreatedContextMenu;
private ContextMenuInfo mContextMenuInfo;
public boolean hasCreatedContextMenu() {
return hasCreatedContextMenu;
}
public ContextMenuInfo getContextMenuInfo() {
return mContextMenuInfo;
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
hasCreatedContextMenu = true;
mContextMenuInfo = menuInfo;
}
}
private static class ImageAdapter extends BaseAdapter {
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setLayoutParams(new Gallery.LayoutParams(136, 88));
return i;
}
private Context mContext;
private Integer[] mImageIds = {
R.drawable.faces,
R.drawable.scenery,
R.drawable.testimage,
R.drawable.faces,
R.drawable.scenery,
R.drawable.testimage,
R.drawable.faces,
R.drawable.scenery,
R.drawable.testimage,
};
}
private static class MockOnItemSelectedListener implements OnItemSelectedListener {
private boolean mIsItemSelected;
private boolean mNothingSelected;
private int mItemSelectedCalledCount;
public boolean isItemSelected() {
return mIsItemSelected;
}
public boolean hasNothingSelected() {
return mNothingSelected;
}
public int getItemSelectedCalledCount() {
return mItemSelectedCalledCount;
}
public void reset() {
mIsItemSelected = false;
mNothingSelected = true;
mItemSelectedCalledCount = 0;
}
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mIsItemSelected = true;
mItemSelectedCalledCount++;
}
public void onNothingSelected(AdapterView<?> parent) {
mNothingSelected = true;
}
}
}