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 DatePickerFocusTest()37 public DatePickerFocusTest() { 38 super(DatePickerActivity.class); 39 } 40 41 @Override setUp()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 */ testFocusTravel()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 sendKey(int keycode)81 private void sendKey(int keycode) { 82 mInstrumentation.sendKeyDownUpSync(keycode); 83 mInstrumentation.waitForIdleSync(); 84 } 85 assertViewHasFocus(final int id)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 sendShiftKey(int keycode)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 */ testYearChoice()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 testArrowThroughDays()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 assertDateIs(int month, final int day, final int year)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 setKnownDate()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