10e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang/*
20e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * Copyright (C) 2013 The Android Open Source Project
30e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang *
40e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * Licensed under the Apache License, Version 2.0 (the "License");
50e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * you may not use this file except in compliance with the License.
60e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * You may obtain a copy of the License at
70e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang *
80e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang *      http://www.apache.org/licenses/LICENSE-2.0
90e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang *
100e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * Unless required by applicable law or agreed to in writing, software
110e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * distributed under the License is distributed on an "AS IS" BASIS,
120e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * See the License for the specific language governing permissions and
140e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * limitations under the License.
150e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang */
160e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wangpackage com.android.uiautomator.common.helpers;
170e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
180e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wangimport com.android.uiautomator.core.UiObject;
190e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wangimport com.android.uiautomator.core.UiObjectNotFoundException;
200e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wangimport com.android.uiautomator.core.UiSelector;
210e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
220e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wangimport java.util.Calendar;
230e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
240e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang/**
250e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * Use this helper anywhere there is a date picker to manage. This helper
260e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang * will set date specified in a Calendar object.
270e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang */
280e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wangpublic class DatePickerHelper {
290e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
300e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static final int MONTH = 0;
310e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static final int DAY = 1;
320e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static final int YEAR = 2;
330e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
340e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static String getCurrentMonth() throws UiObjectNotFoundException {
350e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        return getNumberPickerField(MONTH).getText();
360e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
370e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
380e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static String getCurrentDay() throws UiObjectNotFoundException {
390e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        return getNumberPickerField(DAY).getText();
400e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
410e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
420e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static String getCurrentYear() throws UiObjectNotFoundException {
430e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        return getNumberPickerField(YEAR).getText();
440e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
450e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
460e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void incrementMonth() throws UiObjectNotFoundException {
470e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        incrementMonth(1);
480e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
490e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
500e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void incrementMonth(int count) throws UiObjectNotFoundException {
510e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        for (int x = 0; x < count; x++)
520e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            getNumberPickerIncrementButton(MONTH).click();
530e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
540e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
550e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void decrementMonth() throws UiObjectNotFoundException {
560e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        decrementMonth(1);
570e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
580e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
590e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void decrementMonth(int count) throws UiObjectNotFoundException {
600e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        for (int x = 0; x < count; x++)
610e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            getNumberPickerDecrementButton(MONTH).click();
620e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
630e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
640e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void incrementDay() throws UiObjectNotFoundException {
650e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        incrementDay(1);
660e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
670e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
680e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void incrementDay(int count) throws UiObjectNotFoundException {
690e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        for (int x = 0; x < count; x++)
700e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            getNumberPickerIncrementButton(DAY).click();
710e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
720e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
730e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void decrementDay() throws UiObjectNotFoundException {
740e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        decrementDay(1);
750e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
760e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
770e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void decrementDay(int count) throws UiObjectNotFoundException {
780e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        for (int x = 0; x < count; x++)
790e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            getNumberPickerDecrementButton(DAY).click();
800e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
810e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
820e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void incrementYear() throws UiObjectNotFoundException {
830e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        incrementYear(1);
840e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
850e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
860e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void incrementYear(int count) throws UiObjectNotFoundException {
870e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        for (int x = 0; x < count; x++)
880e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            getNumberPickerIncrementButton(YEAR).click();
890e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
900e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
910e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void decrementYear() throws UiObjectNotFoundException {
920e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        decrementYear(1);
930e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
940e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
950e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void decrementYear(int count) throws UiObjectNotFoundException {
960e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        for (int x = 0; x < count; x++)
970e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            getNumberPickerDecrementButton(YEAR).click();
980e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
990e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1000e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static UiObject getNumberPicker(int instance) {
1010e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        return new UiObject(new UiSelector().className(
1020e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                android.widget.NumberPicker.class.getName()).instance(instance));
1030e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
1040e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1050e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static UiObject getNumberPickerField(int instance)
1060e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            throws UiObjectNotFoundException {
1070e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        return getNumberPicker(instance).getChild(
1080e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                new UiSelector().className(android.widget.EditText.class.getName()));
1090e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
1100e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1110e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static UiObject getNumberPickerDecrementButton(int instance)
1120e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            throws UiObjectNotFoundException {
1130e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        return getNumberPicker(instance).getChild(
1140e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                new UiSelector().className(android.widget.Button.class.getName()).instance(0));
1150e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
1160e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1170e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static UiObject getNumberPickerIncrementButton(int instance)
1180e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            throws UiObjectNotFoundException {
1190e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        return getNumberPicker(instance).getChild(
1200e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                new UiSelector().className(android.widget.Button.class.getName()).instance(1));
1210e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
1220e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1230e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void clickDone() throws UiObjectNotFoundException {
1240e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        new UiObject(new UiSelector().text("Done")).click();
1250e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
1260e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1270e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    public static void setDate(Calendar cal) throws UiObjectNotFoundException {
1280e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        int calYear = cal.get(Calendar.YEAR);
1290e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        int calMonth = cal.get(Calendar.MONTH);
1300e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        int calDay = cal.get(Calendar.DAY_OF_MONTH);
1310e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1320e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        // Adjust day - increment or decrement using the shortest path
1330e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        // while accounting for number of days in month and considering
1340e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        // special case for Feb and leap years.
1350e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        int dpDay = Integer.parseInt(getCurrentDay());
1360e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        if (calDay > dpDay) {
1370e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            if (calDay - dpDay < getDaysInMonth(calYear, calMonth) / 2)
1380e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                incrementDay(calDay - dpDay);
1390e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            else
1400e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                decrementDay(dpDay - calDay + getDaysInMonth(calYear, calMonth));
1410e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        } else if (dpDay > calDay) {
1420e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            if (dpDay - calDay < getDaysInMonth(calYear, calMonth) / 2)
1430e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                decrementDay(dpDay - calDay);
1440e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            else
1450e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                incrementDay(calDay - dpDay + getDaysInMonth(calYear, calMonth));
1460e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        }
1470e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1480e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        // Adjust month - increment or decrement using the shortest path
1490e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        int dpMonth = toMonthNumber(getCurrentMonth());
1500e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        if (calMonth > dpMonth) {
1510e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            if (calMonth - dpMonth < 6)
1520e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                incrementMonth(calMonth - dpMonth);
1530e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            else
1540e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                decrementMonth(dpMonth - calMonth + 12);
1550e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        } else if (dpMonth > calMonth) {
1560e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            if (dpMonth - calMonth < 6)
1570e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                decrementMonth(dpMonth - calMonth);
1580e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            else
1590e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                incrementMonth(calMonth - dpMonth + 12);
1600e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        }
1610e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1620e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        // Adjust year
1630e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        int dpYear = Integer.parseInt(getCurrentYear());
1640e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        if (calYear > dpYear) {
1650e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            incrementYear(calYear - dpYear);
1660e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        } else if (dpYear > calYear) {
1670e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            decrementYear(dpYear - calYear);
1680e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        }
1690e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
1700e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1710e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    private static int toMonthNumber(String monthName) {
1720e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        String months[] = new String[] {"January", "February", "March", "April", "May", "June",
1730e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                "July", "August", "September", "October", "November", "December"};
1740e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1750e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        for (int x = 0; x < months.length; x++) {
1760e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang            if (months[x].contains(monthName))
1770e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang                return x;
1780e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        }
1790e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1800e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        return 0;
1810e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
1820e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang
1830e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    /**
1840e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang     * Get the number of days in the month
1850e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang     * @param year
1860e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang     * @param month
1870e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang     * @return
1880e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang     */
1890e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    private static int getDaysInMonth(int year, int month) {
1900e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        Calendar cal = Calendar.getInstance();
1910e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        cal.set(Calendar.YEAR, year);
1920e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        cal.set(Calendar.MONTH, month);
1930e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang        return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
1940e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang    }
1950e52fd6f867cb9b6a612ef224423a18b34d577f4Xia Wang}
196