1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.widget.focus; 18 19import android.graphics.Rect; 20import android.test.InstrumentationTestCase; 21import android.test.suitebuilder.annotation.LargeTest; 22import android.test.suitebuilder.annotation.MediumTest; 23import android.view.KeyEvent; 24import android.widget.ListView; 25import android.widget.focus.ListOfInternalSelectionViews; 26import android.util.InternalSelectionView; 27 28 29/** 30 * TODO: extract base test case that launches {@link ListOfInternalSelectionViews} with 31 * bundle params. 32 */ 33public class ScrollingThroughListOfFocusablesTest extends InstrumentationTestCase { 34 35 Rect mTempRect = new Rect(); 36 37 private ListOfInternalSelectionViews mActivity; 38 private ListView mListView; 39 40 private int mNumItems = 4; 41 private int mNumRowsPerItem = 5; 42 private double mScreenHeightFactor = 5 /4; 43 44 @Override 45 protected void setUp() throws Exception { 46 mActivity = launchActivity( 47 "com.android.frameworks.coretests", 48 ListOfInternalSelectionViews.class, 49 ListOfInternalSelectionViews.getBundleFor( 50 mNumItems, // 4 items 51 mNumRowsPerItem, // 5 internally selectable rows per item 52 mScreenHeightFactor)); // each item is 5 / 4 screen height tall 53 mListView = mActivity.getListView(); 54 } 55 56 @Override 57 protected void tearDown() throws Exception { 58 mActivity.finish(); 59 super.tearDown(); 60 } 61 62 @MediumTest 63 public void testPreconditions() throws Exception { 64 assertNotNull(mActivity); 65 assertNotNull(mListView); 66 assertEquals(mNumItems, mActivity.getNumItems()); 67 assertEquals(mNumRowsPerItem, mActivity.getNumRowsPerItem()); 68 } 69 70 // TODO: needs to be adjusted to pass on non-HVGA displays 71 // @MediumTest 72 public void testScrollingDownInFirstItem() throws Exception { 73 74 for (int i = 0; i < mNumRowsPerItem; i++) { 75 assertEquals(0, mListView.getSelectedItemPosition()); 76 InternalSelectionView view = mActivity.getSelectedView(); 77 78 assertInternallySelectedRowOnScreen(view, i); 79 80 // move to next row 81 if (i < mNumRowsPerItem - 1) { 82 sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); 83 getInstrumentation().waitForIdleSync(); 84 } 85 } 86 87 { 88 assertEquals(0, mListView.getSelectedItemPosition()); 89 InternalSelectionView view = (InternalSelectionView) 90 mListView.getSelectedView(); 91 92 // 1 pixel tolerance in case height / 4 is not an even number 93 final int fadingEdge = mListView.getBottom() - mListView.getVerticalFadingEdgeLength(); 94 assertTrue("bottom of view should be just above fading edge", 95 view.getBottom() >= fadingEdge - 1 && 96 view.getBottom() <= fadingEdge); 97 } 98 99 100 // make sure fading edge is the expected view 101 { 102 assertEquals("should be a second view visible due to the fading edge", 103 2, mListView.getChildCount()); 104 InternalSelectionView peekingChild = (InternalSelectionView) 105 mListView.getChildAt(1); 106 assertNotNull(peekingChild); 107 assertEquals("wrong value for peeking list item", 108 mActivity.getLabelForPosition(1), peekingChild.getLabel()); 109 } 110 } 111 112 113 @MediumTest 114 public void testScrollingToSecondItem() throws Exception { 115 116 for (int i = 0; i < mNumRowsPerItem; i++) { 117 sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); 118 getInstrumentation().waitForIdleSync(); 119 } 120 121 assertEquals("should have moved to second item", 122 1, mListView.getSelectedItemPosition()); 123 } 124 125 @LargeTest 126 public void testNoFadingEdgeAtBottomOfLastItem() { 127 128 // move down to last item 129 for (int i = 0; i < mNumItems; i++) { 130 for (int j = 0; j < mNumRowsPerItem; j++) { 131 if (i < mNumItems - 1 || j < mNumRowsPerItem - 1) { 132 sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); 133 getInstrumentation().waitForIdleSync(); 134 } 135 } 136 } 137 138 assertEquals(mNumItems - 1, mListView.getSelectedItemPosition()); 139 InternalSelectionView view = mActivity.getSelectedView(); 140 assertEquals(mNumRowsPerItem - 1, view.getSelectedRow()); 141 142 view.getRectForRow(mTempRect, mNumRowsPerItem - 1); 143 mListView.offsetDescendantRectToMyCoords(view, mTempRect); 144 145 assertTrue("bottom of last row of last item should be at " + 146 "the bottom of the list view (no fading edge)", 147 mListView.getBottom() - mListView.getVerticalFadingEdgeLength() < mTempRect.bottom); 148 } 149 150 @LargeTest 151 public void testNavigatingUpThroughInternalSelection() throws Exception { 152 153 // get to bottom of second item 154 for (int i = 0; i < 2; i++) { 155 for (int j = 0; j < mNumRowsPerItem; j++) { 156 if (i < 1 || j < mNumRowsPerItem - 1) { 157 sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); 158 getInstrumentation().waitForIdleSync(); 159 } 160 } 161 } 162 163 164 // (make sure we are at last row of second item) 165 { 166 assertEquals(1, mListView.getSelectedItemPosition()); 167 InternalSelectionView view = mActivity.getSelectedView(); 168 assertEquals(mNumRowsPerItem - 1, view.getSelectedRow()); 169 } 170 171 // go back up to the top of the second item 172 for (int i = mNumRowsPerItem - 1; i >= 0; i--) { 173 assertEquals(1, mListView.getSelectedItemPosition()); 174 InternalSelectionView view = mActivity.getSelectedView(); 175 176 assertInternallySelectedRowOnScreen(view, i); 177 178 // move up to next row 179 if (i > 0) { 180 sendKeys(KeyEvent.KEYCODE_DPAD_UP); 181 getInstrumentation().waitForIdleSync(); 182 } 183 } 184 185 // now we are at top row, should have caused scrolling, and fading edge... 186 { 187 assertEquals(1, mListView.getSelectedItemPosition()); 188 InternalSelectionView view = mActivity.getSelectedView(); 189 assertEquals(0, view.getSelectedRow()); 190 191 view.getDrawingRect(mTempRect); 192 mListView.offsetDescendantRectToMyCoords(view, mTempRect); 193 assertEquals("top of selected row should be just below top vertical fading edge", 194 mListView.getVerticalFadingEdgeLength(), 195 view.getTop()); 196 } 197 198 // make sure fading edge is the view we expect 199 { 200 final InternalSelectionView view = 201 (InternalSelectionView) mListView.getChildAt(0); 202 assertEquals(mActivity.getLabelForPosition(0), view.getLabel()); 203 } 204 205 206 } 207 208 /** 209 * @param internalFocused The view to check 210 * @param row 211 */ 212 private void assertInternallySelectedRowOnScreen( 213 InternalSelectionView internalFocused, 214 int row) { 215 assertEquals("expecting selected row", 216 row, internalFocused.getSelectedRow()); 217 218 internalFocused.getRectForRow(mTempRect, row); 219 mListView.offsetDescendantRectToMyCoords(internalFocused, mTempRect); 220 221 assertTrue("top of row " + row + " should be on sreen", 222 mTempRect.top >= 0); 223 assertTrue("bottom of row " + row + " should be on sreen", 224 mTempRect.bottom < mActivity.getScreenHeight()); 225 } 226} 227