Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 173a5923 authored by Paul Sliwowski's avatar Paul Sliwowski Committed by Android (Google) Code Review
Browse files

Merge "Clean up some of the DaysOfTheWeek and Alarm code." into ics-ub-clock-amazon

parents 5f50e9af 95b88d94
Loading
Loading
Loading
Loading
+111 −90
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.provider.BaseColumns;

import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;

public final class Alarm implements Parcelable {
@@ -53,7 +52,7 @@ public final class Alarm implements Parcelable {
        p.writeInt(enabled ? 1 : 0);
        p.writeInt(hour);
        p.writeInt(minutes);
        p.writeInt(daysOfWeek.getCoded());
        p.writeInt(daysOfWeek.getBitSet());
        // We don't need the alarmTime field anymore, but write 0 to be backwards compatible
        p.writeLong(0);
        p.writeInt(vibrate ? 1 : 0);
@@ -227,18 +226,17 @@ public final class Alarm implements Parcelable {

    // Creates a default alarm at the current time.
    public Alarm() {
        id = -1;
        hour = 0;
        minutes = 0;
        vibrate = true;
        daysOfWeek = new DaysOfWeek(0);
        label = "";
        alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
        this(0, 0);
    }

    public long calculateAlarmTime() {
        // Would it be safe to cache this value in memory?
        return Alarms.calculateAlarm(hour, minutes, daysOfWeek).getTimeInMillis();
    public Alarm(int hour, int minutes) {
        this.id = -1;
        this.hour = hour;
        this.minutes = minutes;
        this.vibrate = true;
        this.daysOfWeek = new DaysOfWeek(0);
        this.label = "";
        this.alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
    }

    public String getLabelOrDefault(Context context) {
@@ -261,6 +259,30 @@ public final class Alarm implements Parcelable {
    }


    public long calculateAlarmTime() {
        // start with now
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(System.currentTimeMillis());

        int nowHour = c.get(Calendar.HOUR_OF_DAY);
        int nowMinute = c.get(Calendar.MINUTE);

        // if alarm is behind current time, advance one day
        if ((hour < nowHour  || (hour == nowHour && minutes <= nowMinute))) {
            c.add(Calendar.DAY_OF_YEAR, 1);
        }
        c.set(Calendar.HOUR_OF_DAY, hour);
        c.set(Calendar.MINUTE, minutes);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);

        int addDays = daysOfWeek.calculateDaysToNextAlarm(c);
        if (addDays > 0) {
            c.add(Calendar.DAY_OF_WEEK, addDays);
        }
        return c.getTimeInMillis();
    }

    /*
     * Days of week code as a single int.
     * 0x00: no day
@@ -272,31 +294,37 @@ public final class Alarm implements Parcelable {
     * 0x20: Saturday
     * 0x40: Sunday
     */
    static final class DaysOfWeek {

        private static int[] DAY_MAP = new int[] {
            Calendar.MONDAY,
            Calendar.TUESDAY,
            Calendar.WEDNESDAY,
            Calendar.THURSDAY,
            Calendar.FRIDAY,
            Calendar.SATURDAY,
            Calendar.SUNDAY,
        };
    public static final class DaysOfWeek {
        // Number if days in the week.
        public static final int DAYS_IN_A_WEEK = 7;

        // Value when all days are set
        public static final int ALL_DAYS_SET = 0x7f;

        private static HashMap<Integer, Integer> DAY_TO_BIT_MASK = new HashMap<Integer, Integer>();
        static {
            for (int i = 0; i < DAY_MAP.length; i++) {
                DAY_TO_BIT_MASK.put(DAY_MAP[i], i);
        // Value when no days are set
        public static final int NO_DAYS_SET = 0;

        /**
         * Need to have monday start at index 0 to be backwards compatible. This converts
         * Calendar.DAY_OF_WEEK constants to our internal bit structure.
         */
        private static int convertDayToBitIndex(int day) {
            return (day + 5) % DAYS_IN_A_WEEK;
        }

        /**
         * Need to have monday start at index 0 to be backwards compatible. This converts
         * our bit structure to Calendar.DAY_OF_WEEK constant value.
         */
        private static int convertBitIndexToDay(int bitIndex) {
            return (bitIndex + 1) % DAYS_IN_A_WEEK + 1;
        }

        // Bitmask of all repeating days
        private int mDays;
        private int mBitSet;

        DaysOfWeek(int days) {
            mDays = days;
        public DaysOfWeek(int bitSet) {
            mBitSet = bitSet;
        }

        public String toString(Context context, boolean showNever) {
@@ -311,21 +339,21 @@ public final class Alarm implements Parcelable {
            StringBuilder ret = new StringBuilder();

            // no days
            if (mDays == 0) {
                return showNever ?
                        context.getText(R.string.never).toString() : "";
            if (mBitSet == NO_DAYS_SET) {
                return showNever ? context.getText(R.string.never).toString() : "";
            }

            // every day
            if (mDays == 0x7f) {
            if (mBitSet == ALL_DAYS_SET) {
                return context.getText(R.string.every_day).toString();
            }

            // count selected days
            int dayCount = 0, days = mDays;
            while (days > 0) {
                if ((days & 1) == 1) dayCount++;
                days >>= 1;
            int dayCount = 0;
            int bitSet = mBitSet;
            while (bitSet > 0) {
                if ((bitSet & 1) == 1) dayCount++;
                bitSet >>= 1;
            }

            // short or long form?
@@ -335,97 +363,90 @@ public final class Alarm implements Parcelable {
                    dfs.getShortWeekdays();

            // selected days
            for (int i = 0; i < 7; i++) {
                if ((mDays & (1 << i)) != 0) {
                    ret.append(dayList[DAY_MAP[i]]);
            for (int bitIndex = 0; bitIndex < DAYS_IN_A_WEEK; bitIndex++) {
                if ((mBitSet & (1 << bitIndex)) != 0) {
                    ret.append(dayList[convertBitIndexToDay(bitIndex)]);
                    dayCount -= 1;
                    if (dayCount > 0) ret.append(
                            context.getText(R.string.day_concat));
                    if (dayCount > 0) ret.append(context.getText(R.string.day_concat));
                }
            }
            return ret.toString();
        }

        private boolean isSet(int day) {
            return ((mDays & (1 << day)) > 0);
        }

        /**
         * Sets the repeat day for the alarm.
         * Enables or disable certain days of the week.
         *
         * @param dayOfWeek One of: Calendar.SUNDAY, Calendar.MONDAY, Calendar.TUESDAY, etc.
         * @param set Whether to set or unset.
         * @param daysOfWeek Calendar.SUNDAY, Calendar.MONDAY, Calendar.TUESDAY, etc.
         */
        public void setDayOfWeek(int dayOfWeek, boolean set) {
            final int bitIndex = DAY_TO_BIT_MASK.get(dayOfWeek);
            set(bitIndex, set);
        public void setDaysOfWeek(boolean value, int ... daysOfWeek) {
            for (int day : daysOfWeek) {
                setBit(convertDayToBitIndex(day), value);
            }
        }

        private boolean isBitEnabled(int bitIndex) {
            return ((mBitSet & (1 << bitIndex)) > 0);
        }

        public void set(int day, boolean set) {
        private void setBit(int bitIndex, boolean set) {
            if (set) {
                mDays |= (1 << day);
                mBitSet |= (1 << bitIndex);
            } else {
                mDays &= ~(1 << day);
                mBitSet &= ~(1 << bitIndex);
            }
        }

        public void set(DaysOfWeek dow) {
            mDays = dow.mDays;
        public void setBitSet(int bitSet) {
            mBitSet = bitSet;
        }

        public int getCoded() {
            return mDays;
        public int getBitSet() {
            return mBitSet;
        }

        public HashSet<Integer> getSetDays() {
            final HashSet<Integer> set = new HashSet<Integer>();
            for (int i = 0; i < 7; i++) {
                if (isSet(i)) {
                    set.add(DAY_MAP[i]);
            for (int bitIndex = 0; bitIndex < DAYS_IN_A_WEEK; bitIndex++) {
                if (isBitEnabled(bitIndex)) {
                    set.add(convertBitIndexToDay(bitIndex));
                }
            }
            return set;
        }

        // Returns days of week encoded in an array of booleans.
        public boolean[] getBooleanArray() {
            boolean[] ret = new boolean[7];
            for (int i = 0; i < 7; i++) {
                ret[i] = isSet(i);
            }
            return ret;
        }

        public boolean isRepeatSet() {
            return mDays != 0;
        public boolean isRepeating() {
            return mBitSet != NO_DAYS_SET;
        }

        /**
         * returns number of days from today until next alarm
         * @param c must be set to today
         * Returns number of days from today until next alarm.
         *
         * @param current must be set to today
         */
        public int getNextAlarm(Calendar c) {
            if (mDays == 0) {
        public int calculateDaysToNextAlarm(Calendar current) {
            if (!isRepeating()) {
                return -1;
            }

            int today = (c.get(Calendar.DAY_OF_WEEK) + 5) % 7;

            int day = 0;
            int dayCount = 0;
            for (; dayCount < 7; dayCount++) {
                day = (today + dayCount) % 7;
                if (isSet(day)) {
            int currentDayBit = convertDayToBitIndex(current.get(Calendar.DAY_OF_WEEK));
            for (; dayCount < DAYS_IN_A_WEEK; dayCount++) {
                int nextAlarmBit = (currentDayBit + dayCount) % DAYS_IN_A_WEEK;
                if (isBitEnabled(nextAlarmBit)) {
                    break;
                }
            }
            return dayCount;
        }

        public void clearAllDays() {
            mBitSet = 0;
        }

        @Override
        public String toString() {
            return "DaysOfWeek{" +
                    "mDays=" + mDays +
                    "mBitSet=" + mBitSet +
                    '}';
        }
    }
+15 −16
Original line number Diff line number Diff line
@@ -767,7 +767,7 @@ public class AlarmClock extends Activity implements LoaderManager.LoaderCallback
            });
            itemHolder.clickableLabel.setOnLongClickListener(mLongClickListener);

            if (mRepeatChecked.contains(alarm.id) || itemHolder.alarm.daysOfWeek.isRepeatSet()) {
            if (mRepeatChecked.contains(alarm.id) || itemHolder.alarm.daysOfWeek.isRepeating()) {
                itemHolder.repeat.setChecked(true);
                itemHolder.repeatDays.setVisibility(View.VISIBLE);
                itemHolder.repeatDays.setOnLongClickListener(mLongClickListener);
@@ -791,13 +791,10 @@ public class AlarmClock extends Activity implements LoaderManager.LoaderCallback
                        // Set all previously set days
                        // or
                        // Set all days if no previous.
                        final int daysOfWeekCoded = mPreviousDaysOfWeekMap.getInt("" + alarm.id);
                        if (daysOfWeekCoded == 0) {
                            for (int day : DAY_ORDER) {
                                alarm.daysOfWeek.setDayOfWeek(day, true);
                            }
                        } else {
                            alarm.daysOfWeek.set(new Alarm.DaysOfWeek(daysOfWeekCoded));
                        final int bitSet = mPreviousDaysOfWeekMap.getInt("" + alarm.id);
                        alarm.daysOfWeek.setBitSet(bitSet);
                        if (!alarm.daysOfWeek.isRepeating()) {
                            alarm.daysOfWeek.setDaysOfWeek(true, DAY_ORDER);
                        }
                        updateDaysOfWeekButtons(itemHolder, alarm.daysOfWeek);
                    } else {
@@ -805,11 +802,11 @@ public class AlarmClock extends Activity implements LoaderManager.LoaderCallback
                        mRepeatChecked.remove(alarm.id);

                        // Remember the set days in case the user wants it back.
                        final int daysOfWeekCoded = alarm.daysOfWeek.getCoded();
                        mPreviousDaysOfWeekMap.putInt("" + alarm.id, daysOfWeekCoded);
                        final int bitSet = alarm.daysOfWeek.getBitSet();
                        mPreviousDaysOfWeekMap.putInt("" + alarm.id, bitSet);

                        // Remove all repeat days
                        alarm.daysOfWeek.set(new Alarm.DaysOfWeek(0));
                        alarm.daysOfWeek.clearAllDays();
                    }
                    asyncUpdateAlarm(alarm, false);
                }
@@ -830,20 +827,22 @@ public class AlarmClock extends Activity implements LoaderManager.LoaderCallback
                        itemHolder.dayButtons[buttonIndex].toggle();
                        final boolean checked = itemHolder.dayButtons[buttonIndex].isChecked();
                        int day = DAY_ORDER[buttonIndex];
                        alarm.daysOfWeek.setDayOfWeek(day, checked);
                        alarm.daysOfWeek.setDaysOfWeek(checked, day);
                        if (checked) {
                            turnOnDayOfWeek(itemHolder, buttonIndex);
                        } else {
                            turnOffDayOfWeek(itemHolder, buttonIndex);

                            // See if this was the last day, if so, un-check the repeat box.
                            if (alarm.daysOfWeek.getCoded() == 0) {
                            if (!alarm.daysOfWeek.isRepeating()) {
                                itemHolder.repeatDays.setVisibility(View.GONE);
                                itemHolder.repeat.setTextColor(mColorDim);
                                mRepeatChecked.remove(alarm.id);

                                // Remember the set days in case the user wants it back.
                                mPreviousDaysOfWeekMap.putInt("" + alarm.id, 0);
                                // Set history to no days, so it will be everyday when repeat is
                                // turned back on
                                mPreviousDaysOfWeekMap.putInt("" + alarm.id,
                                        Alarm.DaysOfWeek.NO_DAYS_SET);
                            }
                        }
                        asyncUpdateAlarm(alarm, false);
@@ -1221,7 +1220,7 @@ public class AlarmClock extends Activity implements LoaderManager.LoaderCallback
    }

    private void popToast(Alarm alarm) {
        AlarmUtils.popAlarmSetToast(this, alarm.hour, alarm.minutes, alarm.daysOfWeek);
        AlarmUtils.popAlarmSetToast(this, alarm);
    }

    /***
+1 −1
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ public class AlarmReceiver extends BroadcastReceiver {
        // Disable the snooze alert if this alarm is the snooze.
        Alarms.disableSnoozeAlert(context, alarm.id);
        // Disable this alarm if it does not repeat.
        if (!alarm.daysOfWeek.isRepeatSet()) {
        if (!alarm.daysOfWeek.isRepeating()) {
            Alarms.enableAlarm(context, alarm.id, false);
        } else {
            // Enable the next alert if there is one. The above call to
+2 −5
Original line number Diff line number Diff line
@@ -84,10 +84,7 @@ public class AlarmUtils {
     * Display a toast that tells the user how long until the alarm
     * goes off.  This helps prevent "am/pm" mistakes.
     */
    public static void popAlarmSetToast(Context context, int hour, int minute,
                                 Alarm.DaysOfWeek daysOfWeek) {
        popAlarmSetToast(context,
                Alarms.calculateAlarm(hour, minute, daysOfWeek)
                        .getTimeInMillis());
    public static void popAlarmSetToast(Context context, Alarm alarm) {
        popAlarmSetToast(context, alarm.calculateAlarmTime());
    }
}
+7 −42
Original line number Diff line number Diff line
@@ -166,7 +166,7 @@ public class Alarms {
                null, null);
    }

    private static ContentValues createContentValues(Alarm alarm) {
    public static ContentValues createContentValues(Alarm alarm) {
        ContentValues values = new ContentValues(8);
        // -1 means generate new id.
        if (alarm.id != -1) {
@@ -178,7 +178,7 @@ public class Alarms {
        values.put(Alarm.Columns.MINUTES, alarm.minutes);
        // We don't need this field anymore
        values.put(Alarm.Columns.ALARM_TIME, 0);
        values.put(Alarm.Columns.DAYS_OF_WEEK, alarm.daysOfWeek.getCoded());
        values.put(Alarm.Columns.DAYS_OF_WEEK, alarm.daysOfWeek.getBitSet());
        values.put(Alarm.Columns.VIBRATE, alarm.vibrate);
        values.put(Alarm.Columns.MESSAGE, alarm.label);

@@ -333,11 +333,10 @@ public class Alarms {
            }
        }

        Alarm alarm = null;
        Long alarmTime = null;
        Pair<Alarm, Long> alarmResult = null;
        for (Alarm a : alarms) {
            // Update the alarm if it has been snoozed
            alarmTime = hasAlarmBeenSnoozed(prefs, a.id) ?
            Long alarmTime = hasAlarmBeenSnoozed(prefs, a.id) ?
                    prefs.getLong(getAlarmPrefSnoozeTimeKey(a.id), -1) :
                    a.calculateAlarmTime();

@@ -349,11 +348,11 @@ public class Alarms {
            }
            if (alarmTime < minTime) {
                minTime = alarmTime;
                alarm = a;
                alarmResult = Pair.create(a, minTime);
            }
        }

        return alarm != null ? Pair.create(alarm, minTime) : null;
        return alarmResult;
    }

    /**
@@ -369,7 +368,7 @@ public class Alarms {
                do {
                    Alarm alarm = new Alarm(cur);
                    // Ignore repeatable alarms
                    if (alarm.daysOfWeek.isRepeatSet()) {
                    if (alarm.daysOfWeek.isRepeating()) {
                        continue;
                    }

@@ -561,40 +560,6 @@ public class Alarms {
        context.sendBroadcast(alarmChanged);
    }

    /**
     * Given an alarm in hours and minutes, return a time suitable for
     * setting in AlarmManager.
     */
    static Calendar calculateAlarm(int hour, int minute,
            Alarm.DaysOfWeek daysOfWeek) {

        // start with now
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(System.currentTimeMillis());

        int nowHour = c.get(Calendar.HOUR_OF_DAY);
        int nowMinute = c.get(Calendar.MINUTE);

        // if alarm is behind current time, advance one day
        if ((hour < nowHour  || (hour == nowHour && minute <= nowMinute))) {
            c.add(Calendar.DAY_OF_YEAR, 1);
        }
        c.set(Calendar.HOUR_OF_DAY, hour);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);

        int addDays = daysOfWeek.getNextAlarm(c);
        if (addDays > 0) c.add(Calendar.DAY_OF_WEEK, addDays);
        return c;
    }

    static String formatTime(final Context context, int hour, int minute,
                             Alarm.DaysOfWeek daysOfWeek) {
        Calendar c = calculateAlarm(hour, minute, daysOfWeek);
        return formatTime(context, c);
    }

    /* used by AlarmAlert */
    static String formatTime(final Context context, Calendar c) {
        String format = get24HourMode(context) ? M24 : M12;
Loading