Home | History | Annotate | Download | only in focus
      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 
     17 package android.widget.focus;
     18 
     19 import android.graphics.Rect;
     20 import android.test.InstrumentationTestCase;
     21 import android.test.suitebuilder.annotation.LargeTest;
     22 import android.test.suitebuilder.annotation.MediumTest;
     23 import android.view.KeyEvent;
     24 import android.widget.ListView;
     25 import android.widget.focus.ListOfInternalSelectionViews;
     26 import android.util.InternalSelectionView;
     27 
     28 
     29 /**
     30  * TODO: extract base test case that launches {@link ListOfInternalSelectionViews} with
     31  * bundle params.
     32  */
     33 public 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