/* * Copyright (C) 2017 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.support.v17.leanback.widget; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import android.content.Context; import android.content.Intent; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.support.v17.leanback.test.R; import android.support.v17.leanback.widget.picker.TimePicker; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @MediumTest @RunWith(AndroidJUnit4.class) public class TimePickerTest { private static final String TAG = "TimePickerTest"; private static final long TRANSITION_LENGTH = 1000; private static final long UPDATE_LENGTH = 1000; Context mContext; View mViewAbove; TimePicker mTimePicker12HourView; TimePicker mTimePicker24HourView; View mViewBelow; @Rule public ActivityTestRule<TimePickerActivity> mActivityTestRule = new ActivityTestRule<>(TimePickerActivity.class, false, false); private TimePickerActivity mActivity; public void initActivity(Intent intent) throws Throwable { mActivity = mActivityTestRule.launchActivity(intent); mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); mTimePicker12HourView = (TimePicker) mActivity.findViewById(R.id.time_picker12); mTimePicker12HourView.setActivatedVisibleItemCount(3); mTimePicker12HourView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mTimePicker12HourView.setActivated(!mTimePicker12HourView.isActivated()); } }); if (intent.getIntExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_with_other_widgets) == R.layout.timepicker_with_other_widgets) { mViewAbove = mActivity.findViewById(R.id.above_picker); mViewBelow = mActivity.findViewById(R.id.below_picker); mTimePicker24HourView = (TimePicker) mActivity.findViewById(R.id.time_picker24); mTimePicker24HourView.setActivatedVisibleItemCount(3); mTimePicker24HourView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mTimePicker24HourView.setActivated(!mTimePicker24HourView.isActivated()); } }); } else if (intent.getIntExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_with_other_widgets) == R.layout.timepicker_alone) { // A layout with only a TimePicker widget that is initially activated. mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setActivated(true); } }); Thread.sleep(500); } } @Test public void testSetHourIn24hFormat() throws Throwable { Intent intent = new Intent(); intent.putExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_with_other_widgets); initActivity(intent); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker24HourView.setHour(0); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker24HourView.getHour(), is(0)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker24HourView.setHour(11); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker24HourView.getHour(), is(11)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker24HourView.setHour(12); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker24HourView.getHour(), is(12)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker24HourView.setHour(13); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker24HourView.getHour(), is(13)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker24HourView.setHour(23); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker24HourView.getHour(), is(23)); } @Test public void testSetHourIn12hFormat() throws Throwable { Intent intent = new Intent(); intent.putExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_with_other_widgets); initActivity(intent); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setHour(0); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker12HourView.getHour(), is(0)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setHour(11); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker12HourView.getHour(), is(11)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setHour(12); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker12HourView.getHour(), is(12)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setHour(13); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker12HourView.getHour(), is(13)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setHour(23); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker12HourView.getHour(), is(23)); } @Test public void testSetMinuteIn24hFormat() throws Throwable { Intent intent = new Intent(); intent.putExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_with_other_widgets); initActivity(intent); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker24HourView.setMinute(0); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker24HourView.getMinute(), is(0)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker24HourView.setMinute(11); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker24HourView.getMinute(), is(11)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker24HourView.setMinute(59); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker24HourView.getMinute(), is(59)); } @Test public void testSetMinuteIn12hFormat() throws Throwable { Intent intent = new Intent(); intent.putExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_with_other_widgets); initActivity(intent); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setMinute(0); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker12HourView.getMinute(), is(0)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setMinute(11); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker12HourView.getMinute(), is(11)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setMinute(59); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour()", mTimePicker12HourView.getMinute(), is(59)); } @Test public void testAmToPmTransition() throws Throwable { Intent intent = new Intent(); intent.putExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_with_other_widgets); initActivity(intent); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setHour(0); mTimePicker12HourView.setMinute(47); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 12-hour mode returns a different hour in getHour()", mTimePicker12HourView.getHour(), is(0)); assertThat("TimePicker in 12-hour mode returns a different hour in getMinute()", mTimePicker12HourView.getMinute(), is(47)); // traverse to the AM/PM column of 12 hour TimePicker widget sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); Thread.sleep(TRANSITION_LENGTH); // Click once to activate sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); Thread.sleep(TRANSITION_LENGTH); sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT); Thread.sleep(TRANSITION_LENGTH); sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT); Thread.sleep(TRANSITION_LENGTH); // scroll down to PM value sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); Thread.sleep(TRANSITION_LENGTH); // Click now to deactivate sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); Thread.sleep(TRANSITION_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns", mTimePicker12HourView.getHour(), is(12)); assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns", mTimePicker12HourView.getMinute(), is(47)); } @Test public void testPmToAmTransition() throws Throwable { Intent intent = new Intent(); intent.putExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_with_other_widgets); initActivity(intent); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setHour(12); mTimePicker12HourView.setMinute(47); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker in 12-hour mode returns a different hour in getHour()", mTimePicker12HourView.getHour(), is(12)); assertThat("TimePicker in 12-hour mode returns a different hour in getMinute()", mTimePicker12HourView.getMinute(), is(47)); // traverse to the AM/PM column of 12 hour TimePicker widget sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); Thread.sleep(TRANSITION_LENGTH); // Click once to activate sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); Thread.sleep(TRANSITION_LENGTH); sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT); Thread.sleep(TRANSITION_LENGTH); sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT); Thread.sleep(TRANSITION_LENGTH); // scroll down to PM value sendKeys(KeyEvent.KEYCODE_DPAD_UP); Thread.sleep(TRANSITION_LENGTH); // Click now to deactivate sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); Thread.sleep(TRANSITION_LENGTH); assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns", mTimePicker12HourView.getHour(), is(0)); assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns", mTimePicker12HourView.getMinute(), is(47)); } @Test public void test12To24HourFormatTransition() throws Throwable { Intent intent = new Intent(); intent.putExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_with_other_widgets); initActivity(intent); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setHour(14); mTimePicker12HourView.setMinute(47); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker should be in 12-hour format.", mTimePicker12HourView.is24Hour(), is(false)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setIs24Hour(true); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker should now be in 24-hour format.", mTimePicker12HourView.is24Hour(), is(true)); // The hour and minute should not be changed. assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns", mTimePicker12HourView.getHour(), is(14)); assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns", mTimePicker12HourView.getMinute(), is(47)); } @Test public void test24To12HourFormatTransition() throws Throwable { Intent intent = new Intent(); intent.putExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_with_other_widgets); initActivity(intent); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker24HourView.setHour(14); mTimePicker24HourView.setMinute(47); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker should be in 12-hour format.", mTimePicker24HourView.is24Hour(), is(true)); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker24HourView.setIs24Hour(false); } }); Thread.sleep(UPDATE_LENGTH); assertThat("TimePicker should now be in 24-hour format.", mTimePicker24HourView.is24Hour(), is(false)); // The hour and minute should not be changed. assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns", mTimePicker24HourView.getHour(), is(14)); assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns", mTimePicker24HourView.getMinute(), is(47)); } @Test public void testInitiallyActiveTimePicker() throws Throwable { Intent intent = new Intent(); intent.putExtra(DatePickerActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.timepicker_alone); initActivity(intent); mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { mTimePicker12HourView.setHour(14); mTimePicker12HourView.setMinute(47); } }); Thread.sleep(UPDATE_LENGTH); ViewGroup mTimePickerInnerView = (ViewGroup) mTimePicker12HourView.findViewById( R.id.picker); assertThat("The first column of TimePicker should initially hold focus", mTimePickerInnerView.getChildAt(0).hasFocus(), is(true)); // focus on first column sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); Thread.sleep(TRANSITION_LENGTH); assertThat("The first column of TimePicker should still hold focus after scrolling down", mTimePickerInnerView.getChildAt(0).hasFocus(), is(true)); // focus on second column sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT); Thread.sleep(TRANSITION_LENGTH); assertThat("The second column of TimePicker should hold focus after scrolling right", mTimePickerInnerView.getChildAt(2).hasFocus(), is(true)); sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); Thread.sleep(TRANSITION_LENGTH); assertThat("The second column of TimePicker should still hold focus after scrolling down", mTimePickerInnerView.getChildAt(2).hasFocus(), is(true)); // focus on third column sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT); Thread.sleep(TRANSITION_LENGTH); assertThat("The third column of TimePicker should hold focus after scrolling right", mTimePickerInnerView.getChildAt(4).hasFocus(), is(true)); sendKeys(KeyEvent.KEYCODE_DPAD_UP); Thread.sleep(TRANSITION_LENGTH); assertThat("The third column of TimePicker should still hold focus after scrolling down", mTimePickerInnerView.getChildAt(4).hasFocus(), is(true)); } private void sendKeys(int ...keys) { for (int i = 0; i < keys.length; i++) { InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(keys[i]); } } }