Merge \"Snooze schedule rules that were canceled by alarms.\" into nyc-mr1-dev

am: ae0aed951b

Change-Id: I18bd8e7528a6c24f350c97268b26fe91ef198290
This commit is contained in:
Julia Reynolds
2016-07-20 20:45:13 +00:00
committed by android-build-merger
3 changed files with 87 additions and 11 deletions

View File

@@ -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;
@@ -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 ====

View File

@@ -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
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) {
return false;
} else {
return isInSchedule;
}
&& time >= mSchedule.nextAlarm;
}
private boolean isInSchedule(int daysOffset, long time, long start, long end) {

View File

@@ -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;
@@ -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;
@@ -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);
}
@@ -97,6 +106,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
public void onConnected() {
if (DEBUG) Slog.d(TAG, "onConnected");
mConnected = true;
readSnoozed();
}
@Override
@@ -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();
}
@@ -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)) {
notifyCondition(conditionId, Condition.STATE_TRUE, "meetsSchedule");
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);
}
@@ -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);
}
@@ -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) {