11d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri/*
21d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri * Copyright (C) 2017 The Android Open Source Project
31d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri *
41d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri * Licensed under the Apache License, Version 2.0 (the "License");
51d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri * you may not use this file except in compliance with the License.
61d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri * You may obtain a copy of the License at
71d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri *
81d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri *      http://www.apache.org/licenses/LICENSE-2.0
91d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri *
101d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri * Unless required by applicable law or agreed to in writing, software
111d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri * distributed under the License is distributed on an "AS IS" BASIS,
121d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri * See the License for the specific language governing permissions and
141d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri * limitations under the License.
151d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri */
161d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
170f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiripackage android.support.v17.leanback.widget.picker;
181d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
191d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport static org.hamcrest.CoreMatchers.is;
201d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport static org.hamcrest.MatcherAssert.assertThat;
210f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiriimport static org.junit.Assert.assertEquals;
221d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
231d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport android.content.Context;
241d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport android.content.Intent;
251d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport android.support.test.InstrumentationRegistry;
26e6cf359406cd7baaa0659b54c1b7d8ac45db122aAurimas Liutikasimport android.support.test.filters.LargeTest;
271d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport android.support.test.rule.ActivityTestRule;
281d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport android.support.test.runner.AndroidJUnit4;
291d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport android.support.v17.leanback.test.R;
301d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport android.view.KeyEvent;
311d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport android.view.View;
321d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport android.view.ViewGroup;
331d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
340f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiriimport org.junit.Before;
351d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport org.junit.Rule;
361d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport org.junit.Test;
371d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiriimport org.junit.runner.RunWith;
381d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
390f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiriimport java.util.Arrays;
400f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiriimport java.util.List;
410f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
42e6cf359406cd7baaa0659b54c1b7d8ac45db122aAurimas Liutikas@LargeTest
431d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri@RunWith(AndroidJUnit4.class)
441d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiripublic class TimePickerTest {
451d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
461d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    private static final String TAG = "TimePickerTest";
471d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    private static final long TRANSITION_LENGTH = 1000;
481d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    private static final long UPDATE_LENGTH = 1000;
491d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
501d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    View mViewAbove;
511d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    TimePicker mTimePicker12HourView;
521d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    TimePicker mTimePicker24HourView;
531d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    View mViewBelow;
541d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
551d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    @Rule
561d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public ActivityTestRule<TimePickerActivity> mActivityTestRule =
571d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            new ActivityTestRule<>(TimePickerActivity.class, false, false);
581d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    private TimePickerActivity mActivity;
590f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri    private Context mContext;
600f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
610f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri    @Before
620f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri    public void setUp() throws Exception {
630f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        mContext = InstrumentationRegistry.getTargetContext();
640f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri    }
651d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
661d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public void initActivity(Intent intent) throws Throwable {
671d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivity = mActivityTestRule.launchActivity(intent);
681d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
691d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mTimePicker12HourView = (TimePicker) mActivity.findViewById(R.id.time_picker12);
701d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mTimePicker12HourView.setActivatedVisibleItemCount(3);
711d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mTimePicker12HourView.setOnClickListener(new View.OnClickListener() {
721d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
731d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void onClick(View v) {
741d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setActivated(!mTimePicker12HourView.isActivated());
751d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
761d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
771d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
780f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        if (intent.getIntExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
791d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_with_other_widgets) == R.layout.timepicker_with_other_widgets) {
801d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            mViewAbove = mActivity.findViewById(R.id.above_picker);
811d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            mViewBelow = mActivity.findViewById(R.id.below_picker);
821d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            mTimePicker24HourView = (TimePicker) mActivity.findViewById(R.id.time_picker24);
831d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            mTimePicker24HourView.setActivatedVisibleItemCount(3);
841d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            mTimePicker24HourView.setOnClickListener(new View.OnClickListener() {
851d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                @Override
861d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                public void onClick(View v) {
871d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                    mTimePicker24HourView.setActivated(!mTimePicker24HourView.isActivated());
881d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                }
891d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            });
900f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        } else if (intent.getIntExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
911d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_with_other_widgets) == R.layout.timepicker_alone) {
921d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            // A layout with only a TimePicker widget that is initially activated.
931d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            mActivityTestRule.runOnUiThread(new Runnable() {
941d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                @Override
951d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                public void run() {
961d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                    mTimePicker12HourView.setActivated(true);
971d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                }
981d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            });
991d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            Thread.sleep(500);
1001d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        }
1011d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
1021d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
1031d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    @Test
1041d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public void testSetHourIn24hFormat() throws Throwable {
1051d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Intent intent = new Intent();
1060f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        intent.putExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
1071d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_with_other_widgets);
1081d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        initActivity(intent);
1090f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
1101d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
1111d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
1121d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
1131d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setHour(0);
1141d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
1151d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
1161d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
1171d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
1181d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.getHour(), is(0));
1191d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
1201d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
1211d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
1221d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
1231d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setHour(11);
1241d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
1251d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
1261d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
1271d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
1281d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.getHour(), is(11));
1291d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
1301d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
1311d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
1321d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
1331d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setHour(12);
1341d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
1351d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
1361d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
1371d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
1381d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.getHour(), is(12));
1391d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
1401d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
1411d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
1421d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
1431d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setHour(13);
1441d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
1451d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
1461d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
1471d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
1481d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.getHour(), is(13));
1491d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
1501d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
1511d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
1521d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
1531d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setHour(23);
1541d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
1551d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
1561d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
1571d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
1581d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.getHour(), is(23));
1591d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
1601d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
1611d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    @Test
1621d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public void testSetHourIn12hFormat() throws Throwable {
1631d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Intent intent = new Intent();
1640f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        intent.putExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
1651d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_with_other_widgets);
1661d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        initActivity(intent);
1671d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
1681d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
1691d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
1701d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setHour(0);
1711d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
1721d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
1731d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
1741d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
1751d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getHour(), is(0));
1761d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
1771d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
1781d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
1791d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
1801d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setHour(11);
1811d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
1821d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
1831d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
1841d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
1851d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getHour(), is(11));
1861d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
1871d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
1881d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
1891d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
1901d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setHour(12);
1911d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
1921d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
1931d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
1941d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
1951d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getHour(), is(12));
1961d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
1971d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
1981d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
1991d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
2001d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setHour(13);
2011d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
2021d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
2031d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
2041d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
2051d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getHour(), is(13));
2061d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
2071d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
2081d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
2091d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
2101d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setHour(23);
2111d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
2121d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
2131d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
2141d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
2151d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getHour(), is(23));
2161d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
2171d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
2181d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    @Test
2191d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public void testSetMinuteIn24hFormat() throws Throwable {
2201d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Intent intent = new Intent();
2210f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        intent.putExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
2221d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_with_other_widgets);
2231d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        initActivity(intent);
2241d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
2251d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
2261d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
2271d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setMinute(0);
2281d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
2291d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
2301d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
2311d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
2321d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.getMinute(), is(0));
2331d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
2341d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
2351d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
2361d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
2371d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setMinute(11);
2381d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
2391d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
2401d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
2411d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
2421d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.getMinute(), is(11));
2431d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
2441d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
2451d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
2461d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
2471d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setMinute(59);
2481d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
2491d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
2501d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
2511d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
2521d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.getMinute(), is(59));
2531d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
2541d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
2551d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    @Test
2561d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public void testSetMinuteIn12hFormat() throws Throwable {
2571d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Intent intent = new Intent();
2580f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        intent.putExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
2591d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_with_other_widgets);
2601d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        initActivity(intent);
2611d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
2621d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
2631d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
2641d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setMinute(0);
2651d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
2661d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
2671d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
2681d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
2691d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getMinute(), is(0));
2701d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
2711d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
2721d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
2731d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
2741d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setMinute(11);
2751d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
2761d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
2771d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
2781d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
2791d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getMinute(), is(11));
2801d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
2811d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
2821d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
2831d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
2841d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setMinute(59);
2851d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
2861d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
2871d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
2881d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour()",
2891d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getMinute(), is(59));
2901d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
2911d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
2921d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
2931d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    @Test
2941d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public void testAmToPmTransition() throws Throwable {
2951d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Intent intent = new Intent();
2960f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        intent.putExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
2971d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_with_other_widgets);
2981d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        initActivity(intent);
2991d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
3001d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
3011d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
3021d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setHour(0);
3031d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setMinute(47);
3041d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
3051d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
3061d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
3071d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 12-hour mode returns a different hour in getHour()",
3081d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getHour(), is(0));
3091d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 12-hour mode returns a different hour in getMinute()",
3101d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getMinute(), is(47));
3111d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
3121d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // traverse to the AM/PM column of 12 hour TimePicker widget
3131d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
3141d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3151d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // Click once to activate
3161d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
3171d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3181d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
3191d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3201d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
3211d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3221d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // scroll down to PM value
3231d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
3241d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3251d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // Click now to deactivate
3261d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
3271d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3281d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
3291d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns",
3301d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getHour(), is(12));
3311d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns",
3321d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getMinute(), is(47));
3331d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
3341d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
3351d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    @Test
3361d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public void testPmToAmTransition() throws Throwable {
3371d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Intent intent = new Intent();
3380f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        intent.putExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
3391d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_with_other_widgets);
3401d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        initActivity(intent);
3411d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
3421d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
3431d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
3441d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setHour(12);
3451d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setMinute(47);
3461d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
3471d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
3481d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
3491d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 12-hour mode returns a different hour in getHour()",
3501d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getHour(), is(12));
3511d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 12-hour mode returns a different hour in getMinute()",
3521d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getMinute(), is(47));
3531d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
3541d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // traverse to the AM/PM column of 12 hour TimePicker widget
3551d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
3561d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3571d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // Click once to activate
3581d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
3591d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3601d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
3611d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3621d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
3631d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3641d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // scroll down to PM value
3651d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
3661d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3671d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // Click now to deactivate
3681d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
3691d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
3701d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
3711d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns",
3721d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getHour(), is(0));
3731d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns",
3741d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getMinute(), is(47));
3751d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
3761d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
3771d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    @Test
3781d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public void test12To24HourFormatTransition() throws Throwable {
3791d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Intent intent = new Intent();
3800f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        intent.putExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
3811d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_with_other_widgets);
3821d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        initActivity(intent);
3831d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
3841d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
3851d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
3861d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setHour(14);
3871d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setMinute(47);
3881d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
3891d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
3901d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
3911d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker should be in 12-hour format.", mTimePicker12HourView.is24Hour(),
3921d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                is(false));
3931d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
3941d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
3951d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
3961d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setIs24Hour(true);
3971d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
3981d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
3991d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
4001d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker should now be in 24-hour format.", mTimePicker12HourView.is24Hour(),
4011d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                is(true));
4021d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // The hour and minute should not be changed.
4031d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns",
4041d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getHour(), is(14));
4051d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns",
4061d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.getMinute(), is(47));
4071d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
4081d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
4091d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    @Test
4101d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public void test24To12HourFormatTransition() throws Throwable {
4111d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Intent intent = new Intent();
4120f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        intent.putExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
4131d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_with_other_widgets);
4141d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        initActivity(intent);
4151d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
4161d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
4171d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
4181d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setHour(14);
4191d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setMinute(47);
4201d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
4211d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
4221d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
4231d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker should be in 12-hour format.", mTimePicker24HourView.is24Hour(),
4241d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                is(true));
4251d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
4261d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
4271d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
4281d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.setIs24Hour(false);
4291d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
4301d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
4311d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
4321d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker should now be in 24-hour format.", mTimePicker24HourView.is24Hour(),
4331d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                is(false));
4341d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // The hour and minute should not be changed.
4351d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns",
4361d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.getHour(), is(14));
4371d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("TimePicker in 24-hour mode returns a different hour in getHour() returns",
4381d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker24HourView.getMinute(), is(47));
4391d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
4401d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
4411d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    @Test
4421d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    public void testInitiallyActiveTimePicker()
4431d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            throws Throwable {
4441d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Intent intent = new Intent();
4450f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        intent.putExtra(TimePickerActivity.EXTRA_LAYOUT_RESOURCE_ID,
4461d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.layout.timepicker_alone);
4471d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        initActivity(intent);
4481d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
4491d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        mActivityTestRule.runOnUiThread(new Runnable() {
4501d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            @Override
4511d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            public void run() {
4521d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setHour(14);
4531d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePicker12HourView.setMinute(47);
4541d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            }
4551d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        });
4561d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(UPDATE_LENGTH);
4571d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
4581d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        ViewGroup mTimePickerInnerView = (ViewGroup) mTimePicker12HourView.findViewById(
4591d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                R.id.picker);
4601d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
4611d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("The first column of TimePicker should initially hold focus",
4621d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePickerInnerView.getChildAt(0).hasFocus(), is(true));
4631d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
4641d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // focus on first column
4651d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
4661d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
4671d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("The first column of TimePicker should still hold focus after scrolling down",
4681d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePickerInnerView.getChildAt(0).hasFocus(), is(true));
4691d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
4701d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // focus on second column
4711d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
4721d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
4731d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("The second column of TimePicker should hold focus after scrolling right",
4741d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePickerInnerView.getChildAt(2).hasFocus(), is(true));
4751d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
4761d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
4771d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
4781d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("The second column of TimePicker should still hold focus after scrolling down",
4791d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri                mTimePickerInnerView.getChildAt(2).hasFocus(), is(true));
4801d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
4811d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        // focus on third column
4821d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
4831d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
4841d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("The third column of TimePicker should hold focus after scrolling right",
4850f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                mTimePickerInnerView.getChildAt(3).hasFocus(), is(true));
4861d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
4871d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
4881d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        Thread.sleep(TRANSITION_LENGTH);
4891d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        assertThat("The third column of TimePicker should still hold focus after scrolling down",
4900f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                mTimePickerInnerView.getChildAt(3).hasFocus(), is(true));
4910f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri    }
4920f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
4930f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri    @Test
4940f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri    public void testExtractSeparatorsForDifferentLocales() throws Throwable {
4950f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        // A typical time pattern for different locales in 12-hour format
4960f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        TimePicker timePicker = new TimePicker(mContext, null) {
4970f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
4980f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            String getBestHourMinutePattern() {
4990f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return "h:mm a";
5000f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5010f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        };
5020f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        List<CharSequence> actualSeparators = timePicker.extractSeparators();
5030f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        List<String> expectedSeparators = Arrays.asList(new String[] {"", ":", "", ""});
5040f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        assertEquals(expectedSeparators, actualSeparators);
5050f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
5060f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        // time pattern for ja_JP in 12 hour format
5070f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        timePicker = new TimePicker(mContext, null) {
5080f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
5090f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            String getBestHourMinutePattern() {
5100f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return "aK:mm";
5110f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5120f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
5130f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
5140f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            public boolean is24Hour() {
5150f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return false;
5160f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5170f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        };
5180f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        actualSeparators = timePicker.extractSeparators();
5190f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        expectedSeparators = Arrays.asList(new String[] {"", "", ":", ""});
5200f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        assertEquals(expectedSeparators, actualSeparators);
5210f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
5220f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        // time pattern for fr_CA in 24 hour format
5230f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        timePicker = new TimePicker(mContext, null) {
5240f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
5250f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            String getBestHourMinutePattern() {
5260f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return "HH 'h' mm";
5270f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5280f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
5290f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
5300f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            public boolean is24Hour() {
5310f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return true;
5320f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5330f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        };
5340f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        actualSeparators = timePicker.extractSeparators();
5350f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        expectedSeparators = Arrays.asList(new String[] {"", "h", ""});
5360f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        assertEquals(expectedSeparators, actualSeparators);
5370f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
5380f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        // time pattern for hsb_DE in 24 hour format
5390f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        timePicker = new TimePicker(mContext, null) {
5400f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
5410f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            String getBestHourMinutePattern() {
5420f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return "H:mm 'hodz'";
5430f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5440f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
5450f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
5460f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            public boolean is24Hour() {
5470f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return true;
5480f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5490f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        };
5500f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        actualSeparators = timePicker.extractSeparators();
5510f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        expectedSeparators = Arrays.asList(new String[] {"", ":", "hodz"});
5520f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        assertEquals(expectedSeparators, actualSeparators);
5530f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
5540f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        // time pattern for ko_KR in 12 hour format
5550f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        timePicker = new TimePicker(mContext, null) {
5560f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
5570f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            String getBestHourMinutePattern() {
5580f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return "a h:mm";
5590f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5600f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
5610f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
5620f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            public boolean is24Hour() {
5630f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return false;
5640f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5650f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        };
5660f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        actualSeparators = timePicker.extractSeparators();
5670f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        expectedSeparators = Arrays.asList(new String[] {"", "", ":", ""});
5680f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        assertEquals(expectedSeparators, actualSeparators);
5690f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
5700f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        // time pattern for fa_IR in 24 hour format
5710f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        timePicker = new TimePicker(mContext, null) {
5720f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
5730f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            String getBestHourMinutePattern() {
5740f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return "H:mm";
5750f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5760f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri
5770f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            @Override
5780f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            public boolean is24Hour() {
5790f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri                return true;
5800f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri            }
5810f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        };
5820f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        actualSeparators = timePicker.extractSeparators();
5830f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        expectedSeparators = Arrays.asList(new String[] {"", ":", ""});
5840f457540aaec9b6fe35301239aaff9209e192ce4Keyvan Amiri        assertEquals(expectedSeparators, actualSeparators);
5851d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
5861d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri
5871d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    private void sendKeys(int ...keys) {
5881d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        for (int i = 0; i < keys.length; i++) {
5891d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri            InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(keys[i]);
5901d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri        }
5911d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri    }
5921d43a78a12bd32b07d299123f3e4f0df19c71f52Keyvan Amiri}
593