diff options
| author | 2014-11-11 16:50:12 +0000 | |
|---|---|---|
| committer | 2014-11-11 16:50:15 +0000 | |
| commit | 73546e535925e6c2902cba10d9da962ba6b39d5f (patch) | |
| tree | 8912ad6b9348bd452620042e29b381c270017e68 | |
| parent | 12403b242f86c0572a99a963fd1e71eda680192b (diff) | |
| parent | 3c984d67ebf07e1215c6b403f0e18e309f2604e9 (diff) | |
Merge "Zen: Exit downtime on next alarm (if mode=none)." into lmp-mr1-dev
| -rw-r--r-- | services/core/java/com/android/server/notification/DowntimeConditionProvider.java | 79 | ||||
| -rw-r--r-- | services/core/java/com/android/server/notification/NextAlarmTracker.java | 4 |
2 files changed, 69 insertions, 14 deletions
diff --git a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java index 24fd155ee234..0fb5732dae50 100644 --- a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java +++ b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java @@ -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(); diff --git a/services/core/java/com/android/server/notification/NextAlarmTracker.java b/services/core/java/com/android/server/notification/NextAlarmTracker.java index d197afd3f9d7..234f5455774f 100644 --- a/services/core/java/com/android/server/notification/NextAlarmTracker.java +++ b/services/core/java/com/android/server/notification/NextAlarmTracker.java @@ -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); } |