/* * Copyright (C) 2007 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.focus; import android.graphics.Rect; import android.test.InstrumentationTestCase; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; import android.util.InternalSelectionView; import android.view.KeyEvent; import android.widget.ListView; /** * TODO: extract base test case that launches {@link ListOfInternalSelectionViews} with * bundle params. */ public class ScrollingThroughListOfFocusablesTest extends InstrumentationTestCase { Rect mTempRect = new Rect(); private ListOfInternalSelectionViews mActivity; private ListView mListView; private int mNumItems = 4; private int mNumRowsPerItem = 5; private double mScreenHeightFactor = 5 /4; @Override protected void setUp() throws Exception { mActivity = launchActivity( "com.android.frameworks.coretests", ListOfInternalSelectionViews.class, ListOfInternalSelectionViews.getBundleFor( mNumItems, // 4 items mNumRowsPerItem, // 5 internally selectable rows per item mScreenHeightFactor)); // each item is 5 / 4 screen height tall mListView = mActivity.getListView(); // Make sure we have some fading edge regardless of ListView style. mListView.setVerticalFadingEdgeEnabled(true); mListView.setFadingEdgeLength(10); ensureNotInTouchMode(); } @Override protected void tearDown() throws Exception { mActivity.finish(); super.tearDown(); } @MediumTest public void testPreconditions() throws Exception { assertNotNull(mActivity); assertNotNull(mListView); assertEquals(mNumItems, mActivity.getNumItems()); assertEquals(mNumRowsPerItem, mActivity.getNumRowsPerItem()); } @MediumTest public void testScrollingDownInFirstItem() throws Exception { for (int i = 0; i < mNumRowsPerItem; i++) { assertEquals(0, mListView.getSelectedItemPosition()); InternalSelectionView view = mActivity.getSelectedView(); assertInternallySelectedRowOnScreen(view, i); // move to next row if (i < mNumRowsPerItem - 1) { sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); getInstrumentation().waitForIdleSync(); } } { assertEquals(0, mListView.getSelectedItemPosition()); InternalSelectionView view = (InternalSelectionView) mListView.getSelectedView(); // 1 pixel tolerance in case height / 4 is not an even number final int bottomFadingEdgeTop = mListView.getBottom() - mListView.getVerticalFadingEdgeLength(); assertTrue("bottom of view should be just above fading edge", view.getBottom() == bottomFadingEdgeTop); } // make sure fading edge is the expected view { assertEquals("should be a second view visible due to the fading edge", 2, mListView.getChildCount()); InternalSelectionView peekingChild = (InternalSelectionView) mListView.getChildAt(1); assertNotNull(peekingChild); assertEquals("wrong value for peeking list item", mActivity.getLabelForPosition(1), peekingChild.getLabel()); } } @MediumTest public void testScrollingToSecondItem() throws Exception { for (int i = 0; i < mNumRowsPerItem; i++) { sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); getInstrumentation().waitForIdleSync(); } assertEquals("should have moved to second item", 1, mListView.getSelectedItemPosition()); } @LargeTest public void testNoFadingEdgeAtBottomOfLastItem() { // move down to last item for (int i = 0; i < mNumItems; i++) { for (int j = 0; j < mNumRowsPerItem; j++) { if (i < mNumItems - 1 || j < mNumRowsPerItem - 1) { sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); getInstrumentation().waitForIdleSync(); } } } assertEquals(mNumItems - 1, mListView.getSelectedItemPosition()); InternalSelectionView view = mActivity.getSelectedView(); assertEquals(mNumRowsPerItem - 1, view.getSelectedRow()); view.getRectForRow(mTempRect, mNumRowsPerItem - 1); mListView.offsetDescendantRectToMyCoords(view, mTempRect); assertTrue("bottom of last row of last item should be at " + "the bottom of the list view (no fading edge)", mListView.getBottom() - mListView.getVerticalFadingEdgeLength() < mTempRect.bottom); } @LargeTest public void testNavigatingUpThroughInternalSelection() throws Exception { // get to bottom of second item for (int i = 0; i < 2; i++) { for (int j = 0; j < mNumRowsPerItem; j++) { if (i < 1 || j < mNumRowsPerItem - 1) { sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); getInstrumentation().waitForIdleSync(); } } } // (make sure we are at last row of second item) { assertEquals(1, mListView.getSelectedItemPosition()); InternalSelectionView view = mActivity.getSelectedView(); assertEquals(mNumRowsPerItem - 1, view.getSelectedRow()); } // go back up to the top of the second item for (int i = mNumRowsPerItem - 1; i >= 0; i--) { assertEquals(1, mListView.getSelectedItemPosition()); InternalSelectionView view = mActivity.getSelectedView(); assertInternallySelectedRowOnScreen(view, i); // move up to next row if (i > 0) { sendKeys(KeyEvent.KEYCODE_DPAD_UP); getInstrumentation().waitForIdleSync(); } } // now we are at top row, should have caused scrolling, and fading edge... { assertEquals(1, mListView.getSelectedItemPosition()); InternalSelectionView view = mActivity.getSelectedView(); assertEquals(0, view.getSelectedRow()); view.getDrawingRect(mTempRect); mListView.offsetDescendantRectToMyCoords(view, mTempRect); assertEquals("top of selected row should be just below top vertical fading edge", mListView.getVerticalFadingEdgeLength(), view.getTop()); } // make sure fading edge is the view we expect { final InternalSelectionView view = (InternalSelectionView) mListView.getChildAt(0); assertEquals(mActivity.getLabelForPosition(0), view.getLabel()); } } /** * @param internalFocused The view to check * @param row */ private void assertInternallySelectedRowOnScreen( InternalSelectionView internalFocused, int row) { assertEquals("expecting selected row", row, internalFocused.getSelectedRow()); internalFocused.getRectForRow(mTempRect, row); mListView.offsetDescendantRectToMyCoords(internalFocused, mTempRect); assertTrue("top of row " + row + " should be on sreen", mTempRect.top >= 0); assertTrue("bottom of row " + row + " should be on sreen", mTempRect.bottom < mActivity.getScreenHeight()); } private void ensureNotInTouchMode() { // If in touch mode inject a DPAD down event to exit that mode. if (mListView.isInTouchMode()) { sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); getInstrumentation().waitForIdleSync(); } } }