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

Commit 1998ee56 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Alarm can end time-based rule.

Bug: 21069008
Change-Id: I857d85a32eb44ca873da4a9f19323c48a922ab9f
parent e979ccb5
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -565,6 +565,10 @@ public class ZenModeConfig implements Parcelable {

    private static boolean safeBoolean(XmlPullParser parser, String att, boolean defValue) {
        final String val = parser.getAttributeValue(null, att);
        return safeBoolean(val, defValue);
    }

    private static boolean safeBoolean(String val, boolean defValue) {
        if (TextUtils.isEmpty(val)) return defValue;
        return Boolean.valueOf(val);
    }
@@ -802,6 +806,7 @@ public class ZenModeConfig implements Parcelable {
                .appendQueryParameter("days", toDayList(schedule.days))
                .appendQueryParameter("start", schedule.startHour + "." + schedule.startMinute)
                .appendQueryParameter("end", schedule.endHour + "." + schedule.endMinute)
                .appendQueryParameter("exitAtAlarm", String.valueOf(schedule.exitAtAlarm))
                .build();
    }

@@ -825,6 +830,7 @@ public class ZenModeConfig implements Parcelable {
        rt.startMinute = start[1];
        rt.endHour = end[0];
        rt.endMinute = end[1];
        rt.exitAtAlarm = safeBoolean(conditionId.getQueryParameter("exitAtAlarm"), false);
        return rt;
    }

@@ -838,6 +844,8 @@ public class ZenModeConfig implements Parcelable {
        public int startMinute;
        public int endHour;
        public int endMinute;
        public boolean exitAtAlarm;
        public long nextAlarm;

        @Override
        public int hashCode() {
@@ -852,7 +860,8 @@ public class ZenModeConfig implements Parcelable {
                    && startHour == other.startHour
                    && startMinute == other.startMinute
                    && endHour == other.endHour
                    && endMinute == other.endMinute;
                    && endMinute == other.endMinute
                    && exitAtAlarm == other.exitAtAlarm;
        }

        public ScheduleInfo copy() {
@@ -865,6 +874,8 @@ public class ZenModeConfig implements Parcelable {
            rt.startMinute = startMinute;
            rt.endHour = endHour;
            rt.endMinute = endMinute;
            rt.exitAtAlarm = exitAtAlarm;
            rt.nextAlarm = nextAlarm;
            return rt;
        }
    }
+2 −2
Original line number Diff line number Diff line
@@ -526,8 +526,8 @@ public class ZenModePanel extends LinearLayout {
            setToMidnight(nextAlarm);

            if (weekRange.compareTo(nextAlarm) >= 0) {
                return ZenModeConfig.toNextAlarmCondition(mContext, now, nextAlarmMs,
                        ActivityManager.getCurrentUser());
                return ZenModeConfig.toNextAlarmCondition(mContext, now,
                        nextAlarmMs, ActivityManager.getCurrentUser());
            }
        }
        return null;
+20 −10
Original line number Diff line number Diff line
@@ -40,16 +40,12 @@ public class ScheduleCalendar {
        updateDays();
    }

    public long nextScheduleStart(long time) {
        if (mSchedule == null || mDays.size() == 0) return Long.MAX_VALUE;
        final long start = getTime(time, mSchedule.startHour, mSchedule.startMinute);
        for (int i = 0; i < Calendar.SATURDAY; i++) {
            final long t = addDays(start, i);
            if (t > time && isInSchedule(t)) {
                return t;
    public void maybeSetNextAlarm(long now, long nextAlarm) {
        if (mSchedule != null) {
            if (mSchedule.exitAtAlarm && now > mSchedule.nextAlarm) {
                mSchedule.nextAlarm = nextAlarm;
            }
        }
        return Long.MAX_VALUE;
    }

    public void setTimeZone(TimeZone tz) {
@@ -60,7 +56,13 @@ public class ScheduleCalendar {
        if (mSchedule == null) return 0;
        final long nextStart = getNextTime(now, mSchedule.startHour, mSchedule.startMinute);
        final long nextEnd = getNextTime(now, mSchedule.endHour, mSchedule.endMinute);
        return Math.min(nextStart, nextEnd);
        long nextScheduleTime = Math.min(nextStart, nextEnd);

        if (mSchedule.exitAtAlarm && mSchedule.nextAlarm > now) {
            return Math.min(nextScheduleTime, mSchedule.nextAlarm);
        } else {
            return nextScheduleTime;
        }
    }

    private long getNextTime(long now, int hr, int min) {
@@ -84,7 +86,15 @@ public class ScheduleCalendar {
        if (end <= start) {
            end = addDays(end, 1);
        }
        return isInSchedule(-1, time, start, end) || isInSchedule(0, time, start, end);
        boolean isInSchedule =
                isInSchedule(-1, time, start, end) || isInSchedule(0, time, start, end);
        if (isInSchedule && mSchedule.exitAtAlarm
                && mSchedule.nextAlarm != 0
                && time >= mSchedule.nextAlarm) {
            return false;
        } else {
            return isInSchedule;
        }
    }

    private boolean isInSchedule(int daysOffset, long time, long start, long end) {
+23 −10
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.notification;

import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -28,7 +29,7 @@ import android.service.notification.Condition;
import android.service.notification.IConditionProvider;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ScheduleInfo;
import android.util.ArraySet;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;

@@ -42,7 +43,7 @@ import java.util.TimeZone;
 */
public class ScheduleConditionProvider extends SystemConditionProviderService {
    private static final String TAG = "ConditionProviders.SCP";
    private static final boolean DEBUG = Log.isLoggable("ConditionProviders", Log.DEBUG);
    private static final boolean DEBUG = true || Log.isLoggable("ConditionProviders", Log.DEBUG);

    public static final ComponentName COMPONENT =
            new ComponentName("android", ScheduleConditionProvider.class.getName());
@@ -53,8 +54,9 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
    private static final String EXTRA_TIME = "time";

    private final Context mContext = this;
    private final ArraySet<Uri> mSubscriptions = new ArraySet<Uri>();
    private final ArrayMap<Uri, ScheduleCalendar> mSubscriptions = new ArrayMap<>();

    private AlarmManager mAlarmManager;
    private boolean mConnected;
    private boolean mRegistered;
    private long mNextAlarmTime;
@@ -80,9 +82,9 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
        pw.print("      mRegistered="); pw.println(mRegistered);
        pw.println("      mSubscriptions=");
        final long now = System.currentTimeMillis();
        for (Uri conditionId : mSubscriptions) {
        for (Uri conditionId : mSubscriptions.keySet()) {
            pw.print("        ");
            pw.print(meetsSchedule(conditionId, now) ? "* " : "  ");
            pw.print(meetsSchedule(mSubscriptions.get(conditionId), now) ? "* " : "  ");
            pw.println(conditionId);
        }
        dumpUpcomingTime(pw, "mNextAlarmTime", mNextAlarmTime, now);
@@ -113,7 +115,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
            notifyCondition(conditionId, Condition.STATE_FALSE, "badCondition");
            return;
        }
        mSubscriptions.add(conditionId);
        mSubscriptions.put(conditionId, toScheduleCalendar(conditionId));
        evaluateSubscriptions();
    }

@@ -135,13 +137,18 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
    }

    private void evaluateSubscriptions() {
        if (mAlarmManager == null) {
            mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        }
        setRegistered(!mSubscriptions.isEmpty());
        final long now = System.currentTimeMillis();
        mNextAlarmTime = 0;
        for (Uri conditionId : mSubscriptions) {
            final ScheduleCalendar cal = toScheduleCalendar(conditionId);
        long nextUserAlarmTime = getNextAlarm();
        for (Uri conditionId : mSubscriptions.keySet()) {
            final ScheduleCalendar cal = mSubscriptions.get(conditionId);
            if (cal != null && cal.isInSchedule(now)) {
                notifyCondition(conditionId, Condition.STATE_TRUE, "meetsSchedule");
                cal.maybeSetNextAlarm(now, nextUserAlarmTime);
            } else {
                notifyCondition(conditionId, Condition.STATE_FALSE, "!meetsSchedule");
            }
@@ -175,8 +182,13 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
        }
    }

    private static boolean meetsSchedule(Uri conditionId, long time) {
        final ScheduleCalendar cal = toScheduleCalendar(conditionId);
    public long getNextAlarm() {
        final AlarmManager.AlarmClockInfo info = mAlarmManager.getNextAlarmClock(
                ActivityManager.getCurrentUser());
        return info != null ? info.getTriggerTime() : 0;
    }

    private static boolean meetsSchedule(ScheduleCalendar cal, long time) {
        return cal != null && cal.isInSchedule(time);
    }

@@ -198,6 +210,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
            filter.addAction(Intent.ACTION_TIME_CHANGED);
            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
            filter.addAction(ACTION_EVALUATE);
            filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
            registerReceiver(mReceiver, filter);
        } else {
            unregisterReceiver(mReceiver);