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