Synchronize on subscription list.
Bug: 27676283
Change-Id: I0382369895ba54abab7e43e28b72495db9f84f94
diff --git a/services/core/java/com/android/server/notification/EventConditionProvider.java b/services/core/java/com/android/server/notification/EventConditionProvider.java
index b13fec1..5bc9b1c 100644
--- a/services/core/java/com/android/server/notification/EventConditionProvider.java
+++ b/services/core/java/com/android/server/notification/EventConditionProvider.java
@@ -44,6 +44,8 @@
import com.android.server.notification.NotificationManagerService.DumpFilter;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
/**
* Built-in zen condition provider for calendar event-based conditions.
@@ -96,10 +98,12 @@
pw.print(" mRegistered="); pw.println(mRegistered);
pw.print(" mBootComplete="); pw.println(mBootComplete);
dumpUpcomingTime(pw, "mNextAlarmTime", mNextAlarmTime, System.currentTimeMillis());
- pw.println(" mSubscriptions=");
- for (Uri conditionId : mSubscriptions) {
- pw.print(" ");
- pw.println(conditionId);
+ synchronized (mSubscriptions) {
+ pw.println(" mSubscriptions=");
+ for (Uri conditionId : mSubscriptions) {
+ pw.print(" ");
+ pw.println(conditionId);
+ }
}
pw.println(" mTrackers=");
for (int i = 0; i < mTrackers.size(); i++) {
@@ -142,19 +146,23 @@
public void onSubscribe(Uri conditionId) {
if (DEBUG) Slog.d(TAG, "onSubscribe " + conditionId);
if (!ZenModeConfig.isValidEventConditionId(conditionId)) {
- notifyCondition(conditionId, Condition.STATE_FALSE, "badCondition");
+ notifyCondition(createCondition(conditionId, Condition.STATE_FALSE));
return;
}
- if (mSubscriptions.add(conditionId)) {
- evaluateSubscriptions();
+ synchronized (mSubscriptions) {
+ if (mSubscriptions.add(conditionId)) {
+ evaluateSubscriptions();
+ }
}
}
@Override
public void onUnsubscribe(Uri conditionId) {
if (DEBUG) Slog.d(TAG, "onUnsubscribe " + conditionId);
- if (mSubscriptions.remove(conditionId)) {
- evaluateSubscriptions();
+ synchronized (mSubscriptions) {
+ if (mSubscriptions.remove(conditionId)) {
+ evaluateSubscriptions();
+ }
}
}
@@ -198,51 +206,61 @@
return;
}
final long now = System.currentTimeMillis();
- for (int i = 0; i < mTrackers.size(); i++) {
- mTrackers.valueAt(i).setCallback(mSubscriptions.isEmpty() ? null : mTrackerCallback);
- }
- setRegistered(!mSubscriptions.isEmpty());
- long reevaluateAt = 0;
- for (Uri conditionId : mSubscriptions) {
- final EventInfo event = ZenModeConfig.tryParseEventConditionId(conditionId);
- if (event == null) {
- notifyCondition(conditionId, Condition.STATE_FALSE, "badConditionId");
- continue;
+ List<Condition> conditionsToNotify = new ArrayList<>();
+ synchronized (mSubscriptions) {
+ for (int i = 0; i < mTrackers.size(); i++) {
+ mTrackers.valueAt(i).setCallback(
+ mSubscriptions.isEmpty() ? null : mTrackerCallback);
}
- CheckEventResult result = null;
- if (event.calendar == null) { // any calendar
- // event could exist on any tracker
- for (int i = 0; i < mTrackers.size(); i++) {
- final CalendarTracker tracker = mTrackers.valueAt(i);
- final CheckEventResult r = tracker.checkEvent(event, now);
- if (result == null) {
- result = r;
- } else {
- result.inEvent |= r.inEvent;
- result.recheckAt = Math.min(result.recheckAt, r.recheckAt);
- }
- }
- } else {
- // event should exist on one tracker
- final int userId = EventInfo.resolveUserId(event.userId);
- final CalendarTracker tracker = mTrackers.get(userId);
- if (tracker == null) {
- Slog.w(TAG, "No calendar tracker found for user " + userId);
- notifyCondition(conditionId, Condition.STATE_FALSE, "badUserId");
+ setRegistered(!mSubscriptions.isEmpty());
+ long reevaluateAt = 0;
+ for (Uri conditionId : mSubscriptions) {
+ final EventInfo event = ZenModeConfig.tryParseEventConditionId(conditionId);
+ if (event == null) {
+ conditionsToNotify.add(createCondition(conditionId, Condition.STATE_FALSE));
continue;
}
- result = tracker.checkEvent(event, now);
+ CheckEventResult result = null;
+ if (event.calendar == null) { // any calendar
+ // event could exist on any tracker
+ for (int i = 0; i < mTrackers.size(); i++) {
+ final CalendarTracker tracker = mTrackers.valueAt(i);
+ final CheckEventResult r = tracker.checkEvent(event, now);
+ if (result == null) {
+ result = r;
+ } else {
+ result.inEvent |= r.inEvent;
+ result.recheckAt = Math.min(result.recheckAt, r.recheckAt);
+ }
+ }
+ } else {
+ // event should exist on one tracker
+ final int userId = EventInfo.resolveUserId(event.userId);
+ final CalendarTracker tracker = mTrackers.get(userId);
+ if (tracker == null) {
+ Slog.w(TAG, "No calendar tracker found for user " + userId);
+ conditionsToNotify.add(createCondition(conditionId, Condition.STATE_FALSE));
+ continue;
+ }
+ result = tracker.checkEvent(event, now);
+ }
+ if (result.recheckAt != 0
+ && (reevaluateAt == 0 || result.recheckAt < reevaluateAt)) {
+ reevaluateAt = result.recheckAt;
+ }
+ if (!result.inEvent) {
+ conditionsToNotify.add(createCondition(conditionId, Condition.STATE_FALSE));
+ continue;
+ }
+ conditionsToNotify.add(createCondition(conditionId, Condition.STATE_TRUE));
}
- if (result.recheckAt != 0 && (reevaluateAt == 0 || result.recheckAt < reevaluateAt)) {
- reevaluateAt = result.recheckAt;
- }
- if (!result.inEvent) {
- notifyCondition(conditionId, Condition.STATE_FALSE, "!inEventNow");
- continue;
- }
- notifyCondition(conditionId, Condition.STATE_TRUE, "inEventNow");
+ rescheduleAlarm(now, reevaluateAt);
}
- rescheduleAlarm(now, reevaluateAt);
+ for (Condition condition : conditionsToNotify) {
+ if (condition != null) {
+ notifyCondition(condition);
+ }
+ }
if (DEBUG) Slog.d(TAG, "evaluateSubscriptions took " + (System.currentTimeMillis() - now));
}
@@ -266,12 +284,6 @@
alarms.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
}
- private void notifyCondition(Uri conditionId, int state, String reason) {
- if (DEBUG) Slog.d(TAG, "notifyCondition " + conditionId + " "
- + Condition.stateToString(state) + " reason=" + reason);
- notifyCondition(createCondition(conditionId, state));
- }
-
private Condition createCondition(Uri id, int state) {
final String summary = NOT_SHOWN;
final String line1 = NOT_SHOWN;