/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.widget; import android.app.Activity; import android.app.Instrumentation; import android.os.SystemClock; import android.test.ActivityInstrumentationTestCase2; import android.view.KeyEvent; import android.view.View; import com.android.frameworks.coretests.R; /** * Test {@link DatePicker} focus changes. */ public class DatePickerFocusTest extends ActivityInstrumentationTestCase2<DatePickerActivity> { private Activity mActivity; private Instrumentation mInstrumentation; private DatePicker mDatePicker; public DatePickerFocusTest() { super(DatePickerActivity.class); } @Override protected void setUp() throws Exception { super.setUp(); mActivity = getActivity(); mInstrumentation = getInstrumentation(); mDatePicker = (DatePicker) mActivity.findViewById(R.id.datePicker); } /** * Tabs (forward and backward) through the DatePicker to ensure the correct * Views gain focus. */ public void testFocusTravel() throws Throwable { runTestOnUiThread(new Runnable() { @Override public void run() { assertTrue(mDatePicker.requestFocus()); } }); assertViewHasFocus(com.android.internal.R.id.date_picker_header_year); sendKey(KeyEvent.KEYCODE_TAB); assertViewHasFocus(com.android.internal.R.id.prev); sendKey(KeyEvent.KEYCODE_TAB); assertViewHasFocus(com.android.internal.R.id.next); sendKey(KeyEvent.KEYCODE_TAB); assertViewHasFocus(com.android.internal.R.id.day_picker_view_pager); sendKey(KeyEvent.KEYCODE_TAB); assertViewHasFocus(R.id.belowPicker); sendShiftKey(KeyEvent.KEYCODE_TAB); assertViewHasFocus(com.android.internal.R.id.day_picker_view_pager); sendShiftKey(KeyEvent.KEYCODE_TAB); assertViewHasFocus(com.android.internal.R.id.next); sendShiftKey(KeyEvent.KEYCODE_TAB); assertViewHasFocus(com.android.internal.R.id.prev); sendShiftKey(KeyEvent.KEYCODE_TAB); assertViewHasFocus(com.android.internal.R.id.date_picker_header_year); } private void sendKey(int keycode) { mInstrumentation.sendKeyDownUpSync(keycode); mInstrumentation.waitForIdleSync(); } private void assertViewHasFocus(final int id) throws Throwable { runTestOnUiThread(new Runnable() { @Override public void run() { View view = mActivity.findViewById(id); assertTrue(view.hasFocus()); } }); } private void sendShiftKey(int keycode) { final KeyEvent shiftDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SHIFT_LEFT); mInstrumentation.sendKeySync(shiftDown); final KeyEvent keyDown = new KeyEvent(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), KeyEvent.ACTION_DOWN, keycode, 0, KeyEvent.META_SHIFT_ON); mInstrumentation.sendKeySync(keyDown); final KeyEvent keyUp = new KeyEvent(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), KeyEvent.ACTION_UP, keycode, 0, KeyEvent.META_SHIFT_ON); mInstrumentation.sendKeySync(keyUp); final KeyEvent shiftUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SHIFT_LEFT); mInstrumentation.sendKeySync(shiftUp); mInstrumentation.waitForIdleSync(); } /** * Tests to ensure the keyboard can select the current year. */ public void testYearChoice() throws Throwable { setKnownDate(); runTestOnUiThread(new Runnable() { @Override public void run() { View year = mDatePicker. findViewById(com.android.internal.R.id.date_picker_header_year); assertTrue(year.requestFocus()); } }); sendKey(KeyEvent.KEYCODE_ENTER); runTestOnUiThread(new Runnable() { @Override public void run() { View yearSelect = mDatePicker. findViewById(com.android.internal.R.id.date_picker_year_picker); assertEquals(yearSelect, mDatePicker.findFocus()); } }); sendKey(KeyEvent.KEYCODE_DPAD_UP); sendKey(KeyEvent.KEYCODE_ENTER); runTestOnUiThread(new Runnable() { @Override public void run() { View yearSelect = mDatePicker. findViewById(com.android.internal.R.id.date_picker_year_picker); assertNotSame(View.VISIBLE, yearSelect.getVisibility()); View year = mDatePicker. findViewById(com.android.internal.R.id.date_picker_header_year); assertTrue(year.hasFocus()); assertEquals(2014, mDatePicker.getYear()); } }); } public void testArrowThroughDays() throws Throwable { setKnownDate(); runTestOnUiThread(new Runnable() { @Override public void run() { View prev = mDatePicker.findViewById(com.android.internal.R.id.next); prev.requestFocus(); } }); sendKey(KeyEvent.KEYCODE_TAB); // Should select the current date and the date shouldn't change sendKey(KeyEvent.KEYCODE_ENTER); assertDateIs(12, 31, 2015); // Move right to January 24, 2016 sendKey(KeyEvent.KEYCODE_DPAD_RIGHT); sendKey(KeyEvent.KEYCODE_ENTER); assertDateIs(1, 24, 2016); // Move down to January 31, 2016 sendKey(KeyEvent.KEYCODE_DPAD_DOWN); sendKey(KeyEvent.KEYCODE_ENTER); assertDateIs(1, 31, 2016); // Move up to January 5, 2016 sendKey(KeyEvent.KEYCODE_DPAD_UP); sendKey(KeyEvent.KEYCODE_DPAD_UP); sendKey(KeyEvent.KEYCODE_DPAD_UP); sendKey(KeyEvent.KEYCODE_DPAD_UP); sendKey(KeyEvent.KEYCODE_DPAD_RIGHT); sendKey(KeyEvent.KEYCODE_DPAD_RIGHT); sendKey(KeyEvent.KEYCODE_ENTER); assertDateIs(1, 5, 2016); // Move up to prev arrow key sendKey(KeyEvent.KEYCODE_DPAD_UP); assertViewHasFocus(com.android.internal.R.id.prev); // tab back into the day-selection pager sendKey(KeyEvent.KEYCODE_TAB); sendKey(KeyEvent.KEYCODE_TAB); sendKey(KeyEvent.KEYCODE_ENTER); assertViewHasFocus(com.android.internal.R.id.day_picker_view_pager); assertDateIs(1, 5, 2016); // Move up out again, then down back into the day-selection pager. // It should land right below the prev button (1/3/2016) sendKey(KeyEvent.KEYCODE_DPAD_UP); sendKey(KeyEvent.KEYCODE_DPAD_DOWN); sendKey(KeyEvent.KEYCODE_ENTER); assertViewHasFocus(com.android.internal.R.id.day_picker_view_pager); assertDateIs(1, 3, 2016); // Move left to previous month (12/12/2015) sendKey(KeyEvent.KEYCODE_DPAD_LEFT); sendKey(KeyEvent.KEYCODE_ENTER); assertDateIs(12, 12, 2015); // Now make sure the start of the month works // Move up to 12/5/2015 and right to 1/1/2016 sendKey(KeyEvent.KEYCODE_DPAD_UP); sendKey(KeyEvent.KEYCODE_DPAD_RIGHT); sendKey(KeyEvent.KEYCODE_ENTER); assertDateIs(1, 1, 2016); // Now make sure the left key goes back to previous month (12/5/2015) sendKey(KeyEvent.KEYCODE_DPAD_LEFT); sendKey(KeyEvent.KEYCODE_ENTER); assertDateIs(12, 5, 2015); // Now go to a mismatched row (no such row on previous month) // This moves over to 1/31/2016 and then left to 12/31/2015 sendKey(KeyEvent.KEYCODE_DPAD_DOWN); sendKey(KeyEvent.KEYCODE_DPAD_DOWN); sendKey(KeyEvent.KEYCODE_DPAD_DOWN); sendKey(KeyEvent.KEYCODE_DPAD_RIGHT); sendKey(KeyEvent.KEYCODE_DPAD_DOWN); sendKey(KeyEvent.KEYCODE_DPAD_DOWN); sendKey(KeyEvent.KEYCODE_DPAD_LEFT); sendKey(KeyEvent.KEYCODE_ENTER); assertDateIs(12, 31, 2015); } private void assertDateIs(int month, final int day, final int year) throws Throwable { final int monthInt = month - 1; // months are 0-based runTestOnUiThread(new Runnable() { @Override public void run() { assertEquals(day, mDatePicker.getDayOfMonth()); assertEquals(year, mDatePicker.getYear()); assertEquals(monthInt, mDatePicker.getMonth()); } }); } private void setKnownDate() throws Throwable { runTestOnUiThread(new Runnable() { @Override public void run() { mDatePicker.updateDate(2015, 11, 31); // December 31, 2015 } }); mInstrumentation.waitForIdleSync(); } }