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

Commit ae0aed95 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents f0de4da4 fe58f1f3
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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 ====
+6 −8
Original line number Diff line number Diff line
@@ -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) {
+75 −2
Original line number Diff line number Diff line
@@ -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)) {
                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) {