Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2008 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;
     18 
     19 import android.app.Activity;
     20 import android.app.Instrumentation;
     21 import android.os.SystemClock;
     22 import android.support.test.filters.LargeTest;
     23 import android.test.ActivityInstrumentationTestCase2;
     24 import android.view.KeyEvent;
     25 import android.view.View;
     26 
     27 import com.android.frameworks.coretests.R;
     28 
     29 /**
     30  * Test {@link DatePicker} focus changes.
     31  */
     32 @LargeTest
     33 public class DatePickerFocusTest extends ActivityInstrumentationTestCase2<DatePickerActivity> {
     34 
     35     private Activity mActivity;
     36     private Instrumentation mInstrumentation;
     37     private DatePicker mDatePicker;
     38 
     39     public DatePickerFocusTest() {
     40         super(DatePickerActivity.class);
     41     }
     42 
     43     @Override
     44     protected void setUp() throws Exception {
     45         super.setUp();
     46 
     47         mActivity = getActivity();
     48         mInstrumentation = getInstrumentation();
     49 
     50         mDatePicker = (DatePicker) mActivity.findViewById(R.id.datePicker);
     51     }
     52 
     53     /**
     54      * Tabs (forward and backward) through the DatePicker to ensure the correct
     55      * Views gain focus.
     56      */
     57     public void testFocusTravel() throws Throwable {
     58         runTestOnUiThread(new Runnable() {
     59             @Override
     60             public void run() {
     61                 assertTrue(mDatePicker.requestFocus());
     62             }
     63         });
     64         assertViewHasFocus(com.android.internal.R.id.date_picker_header_year);
     65         sendKey(KeyEvent.KEYCODE_TAB);
     66         assertViewHasFocus(com.android.internal.R.id.prev);
     67         sendKey(KeyEvent.KEYCODE_TAB);
     68         assertViewHasFocus(com.android.internal.R.id.next);
     69         sendKey(KeyEvent.KEYCODE_TAB);
     70         assertViewHasFocus(com.android.internal.R.id.day_picker_view_pager);
     71         sendKey(KeyEvent.KEYCODE_TAB);
     72         assertViewHasFocus(R.id.belowPicker);
     73         sendShiftKey(KeyEvent.KEYCODE_TAB);
     74         assertViewHasFocus(com.android.internal.R.id.day_picker_view_pager);
     75         sendShiftKey(KeyEvent.KEYCODE_TAB);
     76         assertViewHasFocus(com.android.internal.R.id.next);
     77         sendShiftKey(KeyEvent.KEYCODE_TAB);
     78         assertViewHasFocus(com.android.internal.R.id.prev);
     79         sendShiftKey(KeyEvent.KEYCODE_TAB);
     80         assertViewHasFocus(com.android.internal.R.id.date_picker_header_year);
     81     }
     82 
     83     private void sendKey(int keycode) {
     84         mInstrumentation.sendKeyDownUpSync(keycode);
     85         mInstrumentation.waitForIdleSync();
     86     }
     87 
     88     private void assertViewHasFocus(final int id) throws Throwable {
     89         runTestOnUiThread(new Runnable() {
     90             @Override
     91             public void run() {
     92                 View view = mActivity.findViewById(id);
     93                 assertTrue(view.hasFocus());
     94             }
     95         });
     96     }
     97 
     98     private void sendShiftKey(int keycode) {
     99         final KeyEvent shiftDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SHIFT_LEFT);
    100         mInstrumentation.sendKeySync(shiftDown);
    101 
    102         final KeyEvent keyDown = new KeyEvent(SystemClock.uptimeMillis(),
    103                 SystemClock.uptimeMillis(), KeyEvent.ACTION_DOWN, keycode, 0,
    104                 KeyEvent.META_SHIFT_ON);
    105         mInstrumentation.sendKeySync(keyDown);
    106 
    107         final KeyEvent keyUp = new KeyEvent(SystemClock.uptimeMillis(),
    108                 SystemClock.uptimeMillis(), KeyEvent.ACTION_UP, keycode, 0,
    109                 KeyEvent.META_SHIFT_ON);
    110         mInstrumentation.sendKeySync(keyUp);
    111 
    112         final KeyEvent shiftUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SHIFT_LEFT);
    113         mInstrumentation.sendKeySync(shiftUp);
    114 
    115         mInstrumentation.waitForIdleSync();
    116     }
    117 
    118     /**
    119      * Tests to ensure the keyboard can select the current year.
    120      */
    121     public void testYearChoice() throws Throwable {
    122         setKnownDate();
    123         runTestOnUiThread(new Runnable() {
    124             @Override
    125             public void run() {
    126                 View year = mDatePicker.
    127                         findViewById(com.android.internal.R.id.date_picker_header_year);
    128                 assertTrue(year.requestFocus());
    129             }
    130         });
    131         sendKey(KeyEvent.KEYCODE_ENTER);
    132         runTestOnUiThread(new Runnable() {
    133             @Override
    134             public void run() {
    135                 View yearSelect = mDatePicker.
    136                         findViewById(com.android.internal.R.id.date_picker_year_picker);
    137                 assertEquals(yearSelect, mDatePicker.findFocus());
    138             }
    139         });
    140         sendKey(KeyEvent.KEYCODE_DPAD_UP);
    141         sendKey(KeyEvent.KEYCODE_ENTER);
    142         runTestOnUiThread(new Runnable() {
    143             @Override
    144             public void run() {
    145                 View yearSelect = mDatePicker.
    146                         findViewById(com.android.internal.R.id.date_picker_year_picker);
    147                 assertNotSame(View.VISIBLE, yearSelect.getVisibility());
    148                 View year = mDatePicker.
    149                         findViewById(com.android.internal.R.id.date_picker_header_year);
    150                 assertTrue(year.hasFocus());
    151                 assertEquals(2014, mDatePicker.getYear());
    152             }
    153         });
    154     }
    155 
    156     public void testArrowThroughDays() throws Throwable {
    157         setKnownDate();
    158         runTestOnUiThread(new Runnable() {
    159             @Override
    160             public void run() {
    161                 View prev = mDatePicker.findViewById(com.android.internal.R.id.next);
    162                 prev.requestFocus();
    163             }
    164         });
    165         sendKey(KeyEvent.KEYCODE_TAB);
    166         // Should select the current date and the date shouldn't change
    167         sendKey(KeyEvent.KEYCODE_ENTER);
    168         assertDateIs(12, 31, 2015);
    169         // Move right to January 24, 2016
    170         sendKey(KeyEvent.KEYCODE_DPAD_RIGHT);
    171         sendKey(KeyEvent.KEYCODE_ENTER);
    172         assertDateIs(1, 24, 2016);
    173         // Move down to January 31, 2016
    174         sendKey(KeyEvent.KEYCODE_DPAD_DOWN);
    175         sendKey(KeyEvent.KEYCODE_ENTER);
    176         assertDateIs(1, 31, 2016);
    177         // Move up to January 5, 2016
    178         sendKey(KeyEvent.KEYCODE_DPAD_UP);
    179         sendKey(KeyEvent.KEYCODE_DPAD_UP);
    180         sendKey(KeyEvent.KEYCODE_DPAD_UP);
    181         sendKey(KeyEvent.KEYCODE_DPAD_UP);
    182         sendKey(KeyEvent.KEYCODE_DPAD_RIGHT);
    183         sendKey(KeyEvent.KEYCODE_DPAD_RIGHT);
    184         sendKey(KeyEvent.KEYCODE_ENTER);
    185         assertDateIs(1, 5, 2016);
    186         // Move up to prev arrow key
    187         sendKey(KeyEvent.KEYCODE_DPAD_UP);
    188         assertViewHasFocus(com.android.internal.R.id.prev);
    189         // tab back into the day-selection pager
    190         sendKey(KeyEvent.KEYCODE_TAB);
    191         sendKey(KeyEvent.KEYCODE_TAB);
    192         sendKey(KeyEvent.KEYCODE_ENTER);
    193         assertViewHasFocus(com.android.internal.R.id.day_picker_view_pager);
    194         assertDateIs(1, 5, 2016);
    195 
    196         // Move up out again, then down back into the day-selection pager.
    197         // It should land right below the prev button (1/3/2016)
    198         sendKey(KeyEvent.KEYCODE_DPAD_UP);
    199         sendKey(KeyEvent.KEYCODE_DPAD_DOWN);
    200         sendKey(KeyEvent.KEYCODE_ENTER);
    201         assertViewHasFocus(com.android.internal.R.id.day_picker_view_pager);
    202         assertDateIs(1, 3, 2016);
    203 
    204         // Move left to previous month (12/12/2015)
    205         sendKey(KeyEvent.KEYCODE_DPAD_LEFT);
    206         sendKey(KeyEvent.KEYCODE_ENTER);
    207         assertDateIs(12, 12, 2015);
    208         // Now make sure the start of the month works
    209         // Move up to 12/5/2015 and right to 1/1/2016
    210         sendKey(KeyEvent.KEYCODE_DPAD_UP);
    211         sendKey(KeyEvent.KEYCODE_DPAD_RIGHT);
    212         sendKey(KeyEvent.KEYCODE_ENTER);
    213         assertDateIs(1, 1, 2016);
    214         // Now make sure the left key goes back to previous month (12/5/2015)
    215         sendKey(KeyEvent.KEYCODE_DPAD_LEFT);
    216         sendKey(KeyEvent.KEYCODE_ENTER);
    217         assertDateIs(12, 5, 2015);
    218         // Now go to a mismatched row (no such row on previous month)
    219         // This moves over to 1/31/2016 and then left to 12/31/2015
    220         sendKey(KeyEvent.KEYCODE_DPAD_DOWN);
    221         sendKey(KeyEvent.KEYCODE_DPAD_DOWN);
    222         sendKey(KeyEvent.KEYCODE_DPAD_DOWN);
    223         sendKey(KeyEvent.KEYCODE_DPAD_RIGHT);
    224         sendKey(KeyEvent.KEYCODE_DPAD_DOWN);
    225         sendKey(KeyEvent.KEYCODE_DPAD_DOWN);
    226         sendKey(KeyEvent.KEYCODE_DPAD_LEFT);
    227         sendKey(KeyEvent.KEYCODE_ENTER);
    228         assertDateIs(12, 31, 2015);
    229     }
    230 
    231     private void assertDateIs(int month, final int day, final int year) throws Throwable {
    232         final int monthInt = month - 1; // months are 0-based
    233         runTestOnUiThread(new Runnable() {
    234             @Override
    235             public void run() {
    236                 assertEquals(day, mDatePicker.getDayOfMonth());
    237                 assertEquals(year, mDatePicker.getYear());
    238                 assertEquals(monthInt, mDatePicker.getMonth());
    239             }
    240         });
    241     }
    242 
    243     private void setKnownDate() throws Throwable {
    244         runTestOnUiThread(new Runnable() {
    245             @Override
    246             public void run() {
    247                 mDatePicker.updateDate(2015, 11, 31); // December 31, 2015
    248             }
    249         });
    250         mInstrumentation.waitForIdleSync();
    251     }
    252 }
    253