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

Commit f4a53c6d authored by John Spurlock's avatar John Spurlock Committed by Android Git Automerger
Browse files

am 6044b5f3: am 73546e53: Merge "Zen: Exit downtime on next alarm (if...

am 6044b5f3: am 73546e53: Merge "Zen: Exit downtime on next alarm (if mode=none)." into lmp-mr1-dev automerge: 3069aa20

* commit '6044b5f3':
  Zen: Exit downtime on next alarm (if mode=none).
parents ed226077 6044b5f3
Loading
Loading
Loading
Loading
+67 −12
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.notification;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.AlarmManager.AlarmClockInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -63,8 +64,10 @@ public class DowntimeConditionProvider extends ConditionProviderService {
    private final Calendar mCalendar = Calendar.getInstance();
    private final Context mContext = this;
    private final ArraySet<Integer> mDays = new ArraySet<Integer>();
    private final ArraySet<Long> mFiredAlarms = new ArraySet<Long>();

    private boolean mConnected;
    private NextAlarmTracker mTracker;
    private int mDowntimeMode;
    private ZenModeConfig mConfig;
    private Callback mCallback;
@@ -77,6 +80,7 @@ public class DowntimeConditionProvider extends ConditionProviderService {
        pw.println("    DowntimeConditionProvider:");
        pw.print("      mConnected="); pw.println(mConnected);
        pw.print("      mDowntimeMode="); pw.println(Global.zenModeToString(mDowntimeMode));
        pw.print("      mFiredAlarms="); pw.println(mFiredAlarms);
    }

    public void attachBase(Context base) {
@@ -101,12 +105,15 @@ public class DowntimeConditionProvider extends ConditionProviderService {
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        mContext.registerReceiver(mReceiver, filter);
        mTracker = mCallback.getNextAlarmTracker();
        mTracker.addCallback(mTrackerCallback);
        init();
    }

    @Override
    public void onDestroy() {
        if (DEBUG) Slog.d(TAG, "onDestroy");
        mTracker.removeCallback(mTrackerCallback);
        mConnected = false;
    }

@@ -183,35 +190,52 @@ public class DowntimeConditionProvider extends ConditionProviderService {
        }
    }

    private int computeDowntimeMode(long time) {
        if (mConfig == null || mDays.size() == 0) return Global.ZEN_MODE_OFF;
    private boolean isInDowntime(long time) {
        if (mConfig == null || mDays.size() == 0) return false;
        final long start = getTime(time, mConfig.sleepStartHour, mConfig.sleepStartMinute);
        long end = getTime(time, mConfig.sleepEndHour, mConfig.sleepEndMinute);
        if (start == end) return Global.ZEN_MODE_OFF;
        if (start == end) return false;
        if (end < start) {
            end = addDays(end, 1);
        }
        final boolean inDowntime = isInDowntime(-1, time, start, end)
                || isInDowntime(0, time, start, end);
        return inDowntime ? (mConfig.sleepNone ? Global.ZEN_MODE_NO_INTERRUPTIONS
                : Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) : Global.ZEN_MODE_OFF;
        final boolean orAlarm = mConfig.sleepNone;
        return isInDowntime(-1, time, start, end, orAlarm)
                || isInDowntime(0, time, start, end, orAlarm);
    }

    private boolean isInDowntime(int daysOffset, long time, long start, long end) {
    private boolean isInDowntime(int daysOffset, long time, long start, long end, boolean orAlarm) {
        final int n = Calendar.SATURDAY;
        final int day = ((getDayOfWeek(time) - 1) + (daysOffset % n) + n) % n + 1;
        start = addDays(start, daysOffset);
        end = addDays(end, daysOffset);
        if (orAlarm) {
            end = findFiredAlarm(start, end);
        }
        return mDays.contains(day) && time >= start && time < end;
    }

    private long findFiredAlarm(long start, long end) {
        final int N = mFiredAlarms.size();
        for (int i = 0; i < N; i++) {
            final long firedAlarm = mFiredAlarms.valueAt(i);
            if (firedAlarm > start && firedAlarm < end) {
                return firedAlarm;
            }
        }
        return end;
    }

    private void reevaluateDowntime() {
        final int downtimeMode = computeDowntimeMode(System.currentTimeMillis());
        final long now = System.currentTimeMillis();
        final boolean inDowntimeNow = isInDowntime(now);
        final int downtimeMode = inDowntimeNow ? (mConfig.sleepNone
                ? Global.ZEN_MODE_NO_INTERRUPTIONS : Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
                : Global.ZEN_MODE_OFF;
        if (DEBUG) Slog.d(TAG, "downtimeMode=" + downtimeMode);
        if (downtimeMode == mDowntimeMode) return;
        mDowntimeMode = downtimeMode;
        Slog.i(TAG, (isInDowntime() ? "Entering" : "Exiting" ) + " downtime");
        ZenLog.traceDowntime(mDowntimeMode, getDayOfWeek(System.currentTimeMillis()), mDays);
        ZenLog.traceDowntime(mDowntimeMode, getDayOfWeek(now), mDays);
        fireDowntimeChanged();
    }

@@ -266,8 +290,8 @@ public class DowntimeConditionProvider extends ConditionProviderService {
                PendingIntent.FLAG_UPDATE_CURRENT);
        alarms.cancel(pendingIntent);
        if (mConfig.sleepMode != null) {
            if (DEBUG) Slog.d(TAG, String.format("Scheduling %s for %s, %s in the future, now=%s",
                    action, ts(time), time - now, ts(now)));
            if (DEBUG) Slog.d(TAG, String.format("Scheduling %s for %s, in %s, now=%s",
                    action, ts(time), NextAlarmTracker.formatDuration(time - now), ts(now)));
            alarms.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
        }
    }
@@ -276,6 +300,30 @@ public class DowntimeConditionProvider extends ConditionProviderService {
        return new Date(time) + " (" + time + ")";
    }

    private void onEvaluateNextAlarm(AlarmClockInfo nextAlarm, long wakeupTime, boolean booted) {
        if (!booted) return;  // we don't know yet
        if (nextAlarm == null) return;  // not fireable
        if (DEBUG) Slog.d(TAG, "onEvaluateNextAlarm " + mTracker.formatAlarmDebug(nextAlarm));
        if (System.currentTimeMillis() > wakeupTime) {
            if (DEBUG) Slog.d(TAG, "Alarm fired: " + mTracker.formatAlarmDebug(wakeupTime));
            trimFiredAlarms();
            mFiredAlarms.add(wakeupTime);
        }
        reevaluateDowntime();
    }

    private void trimFiredAlarms() {
        // remove fired alarms over 2 days old
        final long keepAfter = System.currentTimeMillis() - 2 * 24 * 60 * 60 * 1000;
        final int N = mFiredAlarms.size();
        for (int i = N - 1; i >= 0; i--) {
            final long firedAlarm = mFiredAlarms.valueAt(i);
            if (firedAlarm < keepAfter) {
                mFiredAlarms.removeAt(i);
            }
        }
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
@@ -296,6 +344,13 @@ public class DowntimeConditionProvider extends ConditionProviderService {
        }
    };

    private final NextAlarmTracker.Callback mTrackerCallback = new NextAlarmTracker.Callback() {
        @Override
        public void onEvaluate(AlarmClockInfo nextAlarm, long wakeupTime, boolean booted) {
            DowntimeConditionProvider.this.onEvaluateNextAlarm(nextAlarm, wakeupTime, booted);
        }
    };

    public interface Callback {
        void onDowntimeChanged(int downtimeMode);
        NextAlarmTracker getNextAlarmTracker();
+2 −2
Original line number Diff line number Diff line
@@ -176,7 +176,7 @@ public class NextAlarmTracker {
        return true;
    }

    private static String formatDuration(long millis) {
    public static String formatDuration(long millis) {
        final StringBuilder sb = new StringBuilder();
        TimeUtils.formatDuration(millis, sb);
        return sb.toString();
@@ -196,7 +196,7 @@ public class NextAlarmTracker {
        return DateFormat.format(pattern, time).toString();
    }

    private String formatAlarmDebug(AlarmClockInfo alarm) {
    public String formatAlarmDebug(AlarmClockInfo alarm) {
        return formatAlarmDebug(alarm != null ? alarm.getTriggerTime() : 0);
    }