Loading core/java/android/service/notification/ZenModeConfig.java +6 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import java.util.Objects; Loading Loading @@ -896,9 +897,13 @@ public class ZenModeConfig implements Parcelable { ", endHour=" + endHour + ", endMinute=" + endMinute + ", exitAtAlarm=" + exitAtAlarm + ", nextAlarm=" + nextAlarm + ", nextAlarm=" + ts(nextAlarm) + '}'; } protected static String ts(long time) { return new Date(time) + " (" + time + ")"; } } // ==== Built-in system condition: event ==== Loading services/core/java/com/android/server/notification/ScheduleCalendar.java +6 −8 Original line number Diff line number Diff line Loading @@ -82,15 +82,13 @@ public class ScheduleCalendar { if (end <= start) { end = addDays(end, 1); } 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; return isInSchedule(-1, time, start, end) || isInSchedule(0, time, start, end); } public boolean shouldExitForAlarm(long time) { return mSchedule.exitAtAlarm && mSchedule.nextAlarm != 0 && time >= mSchedule.nextAlarm; } private boolean isInSchedule(int daysOffset, long time, long start, long end) { Loading services/core/java/com/android/server/notification/ScheduleConditionProvider.java +75 −2 Original line number Diff line number Diff line Loading @@ -25,11 +25,15 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Binder; import android.provider.Settings; import android.service.notification.Condition; import android.service.notification.IConditionProvider; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ScheduleInfo; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.Slog; Loading @@ -53,9 +57,13 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { private static final String ACTION_EVALUATE = SIMPLE_NAME + ".EVALUATE"; private static final int REQUEST_CODE_EVALUATE = 1; private static final String EXTRA_TIME = "time"; private static final String SEPARATOR = ";"; private static final String SCP_SETTING = "snoozed_schedule_condition_provider"; private final Context mContext = this; private final ArrayMap<Uri, ScheduleCalendar> mSubscriptions = new ArrayMap<>(); private ArraySet<Uri> mSnoozed = new ArraySet<>(); private AlarmManager mAlarmManager; private boolean mConnected; Loading Loading @@ -90,6 +98,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { pw.print(" "); pw.println(mSubscriptions.get(conditionId).toString()); } pw.println(" snoozed due to alarm: " + TextUtils.join(SEPARATOR, mSnoozed)); dumpUpcomingTime(pw, "mNextAlarmTime", mNextAlarmTime, now); } Loading @@ -97,6 +106,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { public void onConnected() { if (DEBUG) Slog.d(TAG, "onConnected"); mConnected = true; readSnoozed(); } @Override Loading Loading @@ -126,6 +136,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { public void onUnsubscribe(Uri conditionId) { if (DEBUG) Slog.d(TAG, "onUnsubscribe " + conditionId); mSubscriptions.remove(conditionId); removeSnoozed(conditionId); evaluateSubscriptions(); } Loading @@ -150,10 +161,16 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { for (Uri conditionId : mSubscriptions.keySet()) { final ScheduleCalendar cal = mSubscriptions.get(conditionId); if (cal != null && cal.isInSchedule(now)) { if (conditionSnoozed(conditionId) || cal.shouldExitForAlarm(now)) { notifyCondition(conditionId, Condition.STATE_FALSE, "alarmCanceled"); addSnoozed(conditionId); } else { notifyCondition(conditionId, Condition.STATE_TRUE, "meetsSchedule"); } cal.maybeSetNextAlarm(now, nextUserAlarmTime); } else { notifyCondition(conditionId, Condition.STATE_FALSE, "!meetsSchedule"); removeSnoozed(conditionId); if (nextUserAlarmTime == 0) { cal.maybeSetNextAlarm(now, nextUserAlarmTime); } Loading Loading @@ -194,7 +211,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { return info != null ? info.getTriggerTime() : 0; } private static boolean meetsSchedule(ScheduleCalendar cal, long time) { private boolean meetsSchedule(ScheduleCalendar cal, long time) { return cal != null && cal.isInSchedule(time); } Loading Loading @@ -237,6 +254,62 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { return new Condition(id, summary, line1, line2, 0, state, Condition.FLAG_RELEVANT_ALWAYS); } private boolean conditionSnoozed(Uri conditionId) { synchronized (mSnoozed) { return mSnoozed.contains(conditionId); } } private void addSnoozed(Uri conditionId) { synchronized (mSnoozed) { mSnoozed.add(conditionId); saveSnoozedLocked(); } } private void removeSnoozed(Uri conditionId) { synchronized (mSnoozed) { mSnoozed.remove(conditionId); saveSnoozedLocked(); } } public void saveSnoozedLocked() { final String setting = TextUtils.join(SEPARATOR, mSnoozed); final int currentUser = ActivityManager.getCurrentUser(); Settings.Secure.putStringForUser(mContext.getContentResolver(), SCP_SETTING, setting, currentUser); } public void readSnoozed() { synchronized (mSnoozed) { long identity = Binder.clearCallingIdentity(); try { final String setting = Settings.Secure.getStringForUser( mContext.getContentResolver(), SCP_SETTING, ActivityManager.getCurrentUser()); if (setting != null) { final String[] tokens = setting.split(SEPARATOR); for (int i = 0; i < tokens.length; i++) { String token = tokens[i]; if (token != null) { token = token.trim(); } if (TextUtils.isEmpty(token)) { continue; } mSnoozed.add(Uri.parse(token)); } } } finally { Binder.restoreCallingIdentity(identity); } } } private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading Loading
core/java/android/service/notification/ZenModeConfig.java +6 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import java.util.Objects; Loading Loading @@ -896,9 +897,13 @@ public class ZenModeConfig implements Parcelable { ", endHour=" + endHour + ", endMinute=" + endMinute + ", exitAtAlarm=" + exitAtAlarm + ", nextAlarm=" + nextAlarm + ", nextAlarm=" + ts(nextAlarm) + '}'; } protected static String ts(long time) { return new Date(time) + " (" + time + ")"; } } // ==== Built-in system condition: event ==== Loading
services/core/java/com/android/server/notification/ScheduleCalendar.java +6 −8 Original line number Diff line number Diff line Loading @@ -82,15 +82,13 @@ public class ScheduleCalendar { if (end <= start) { end = addDays(end, 1); } 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; return isInSchedule(-1, time, start, end) || isInSchedule(0, time, start, end); } public boolean shouldExitForAlarm(long time) { return mSchedule.exitAtAlarm && mSchedule.nextAlarm != 0 && time >= mSchedule.nextAlarm; } private boolean isInSchedule(int daysOffset, long time, long start, long end) { Loading
services/core/java/com/android/server/notification/ScheduleConditionProvider.java +75 −2 Original line number Diff line number Diff line Loading @@ -25,11 +25,15 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Binder; import android.provider.Settings; import android.service.notification.Condition; import android.service.notification.IConditionProvider; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ScheduleInfo; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.Slog; Loading @@ -53,9 +57,13 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { private static final String ACTION_EVALUATE = SIMPLE_NAME + ".EVALUATE"; private static final int REQUEST_CODE_EVALUATE = 1; private static final String EXTRA_TIME = "time"; private static final String SEPARATOR = ";"; private static final String SCP_SETTING = "snoozed_schedule_condition_provider"; private final Context mContext = this; private final ArrayMap<Uri, ScheduleCalendar> mSubscriptions = new ArrayMap<>(); private ArraySet<Uri> mSnoozed = new ArraySet<>(); private AlarmManager mAlarmManager; private boolean mConnected; Loading Loading @@ -90,6 +98,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { pw.print(" "); pw.println(mSubscriptions.get(conditionId).toString()); } pw.println(" snoozed due to alarm: " + TextUtils.join(SEPARATOR, mSnoozed)); dumpUpcomingTime(pw, "mNextAlarmTime", mNextAlarmTime, now); } Loading @@ -97,6 +106,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { public void onConnected() { if (DEBUG) Slog.d(TAG, "onConnected"); mConnected = true; readSnoozed(); } @Override Loading Loading @@ -126,6 +136,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { public void onUnsubscribe(Uri conditionId) { if (DEBUG) Slog.d(TAG, "onUnsubscribe " + conditionId); mSubscriptions.remove(conditionId); removeSnoozed(conditionId); evaluateSubscriptions(); } Loading @@ -150,10 +161,16 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { for (Uri conditionId : mSubscriptions.keySet()) { final ScheduleCalendar cal = mSubscriptions.get(conditionId); if (cal != null && cal.isInSchedule(now)) { if (conditionSnoozed(conditionId) || cal.shouldExitForAlarm(now)) { notifyCondition(conditionId, Condition.STATE_FALSE, "alarmCanceled"); addSnoozed(conditionId); } else { notifyCondition(conditionId, Condition.STATE_TRUE, "meetsSchedule"); } cal.maybeSetNextAlarm(now, nextUserAlarmTime); } else { notifyCondition(conditionId, Condition.STATE_FALSE, "!meetsSchedule"); removeSnoozed(conditionId); if (nextUserAlarmTime == 0) { cal.maybeSetNextAlarm(now, nextUserAlarmTime); } Loading Loading @@ -194,7 +211,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { return info != null ? info.getTriggerTime() : 0; } private static boolean meetsSchedule(ScheduleCalendar cal, long time) { private boolean meetsSchedule(ScheduleCalendar cal, long time) { return cal != null && cal.isInSchedule(time); } Loading Loading @@ -237,6 +254,62 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { return new Condition(id, summary, line1, line2, 0, state, Condition.FLAG_RELEVANT_ALWAYS); } private boolean conditionSnoozed(Uri conditionId) { synchronized (mSnoozed) { return mSnoozed.contains(conditionId); } } private void addSnoozed(Uri conditionId) { synchronized (mSnoozed) { mSnoozed.add(conditionId); saveSnoozedLocked(); } } private void removeSnoozed(Uri conditionId) { synchronized (mSnoozed) { mSnoozed.remove(conditionId); saveSnoozedLocked(); } } public void saveSnoozedLocked() { final String setting = TextUtils.join(SEPARATOR, mSnoozed); final int currentUser = ActivityManager.getCurrentUser(); Settings.Secure.putStringForUser(mContext.getContentResolver(), SCP_SETTING, setting, currentUser); } public void readSnoozed() { synchronized (mSnoozed) { long identity = Binder.clearCallingIdentity(); try { final String setting = Settings.Secure.getStringForUser( mContext.getContentResolver(), SCP_SETTING, ActivityManager.getCurrentUser()); if (setting != null) { final String[] tokens = setting.split(SEPARATOR); for (int i = 0; i < tokens.length; i++) { String token = tokens[i]; if (token != null) { token = token.trim(); } if (TextUtils.isEmpty(token)) { continue; } mSnoozed.add(Uri.parse(token)); } } } finally { Binder.restoreCallingIdentity(identity); } } } private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading