Merge "Prevent notifications from erroroneously bypassing 'repeat callers' filter" into nyc-mr1-dev

This commit is contained in:
TreeHugger Robot
2016-07-19 20:05:42 +00:00
committed by Android (Google) Code Review
3 changed files with 48 additions and 12 deletions

View File

@@ -3150,6 +3150,12 @@ public class NotificationManagerService extends SystemService {
} }
} }
private void recordCallerLocked(NotificationRecord record) {
if (mZenModeHelper.isCall(record)) {
mZenModeHelper.recordCaller(record);
}
}
// let zen mode evaluate this record // let zen mode evaluate this record
private void applyZenModeLocked(NotificationRecord record) { private void applyZenModeLocked(NotificationRecord record) {
record.setIntercepted(mZenModeHelper.shouldIntercept(record)); record.setIntercepted(mZenModeHelper.shouldIntercept(record));
@@ -3289,6 +3295,10 @@ public class NotificationManagerService extends SystemService {
} }
private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete, int reason) { private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete, int reason) {
// Record caller.
recordCallerLocked(r);
// tell the app // tell the app
if (sendDelete) { if (sendDelete) {
if (r.getNotification().deleteIntent != null) { if (r.getNotification().deleteIntent != null) {

View File

@@ -81,7 +81,9 @@ public class ZenModeFiltering {
if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) return false; // nothing gets through if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) return false; // nothing gets through
if (zen == Global.ZEN_MODE_ALARMS) return false; // not an alarm if (zen == Global.ZEN_MODE_ALARMS) return false; // not an alarm
if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
if (config.allowRepeatCallers && REPEAT_CALLERS.isRepeat(context, extras)) return true; if (config.allowRepeatCallers && REPEAT_CALLERS.isRepeat(context, extras)) {
return true;
}
if (!config.allowCalls) return false; // no other calls get through if (!config.allowCalls) return false; // no other calls get through
if (validator != null) { if (validator != null) {
final float contactAffinity = validator.getContactAffinity(userHandle, extras, final float contactAffinity = validator.getContactAffinity(userHandle, extras,
@@ -97,6 +99,10 @@ public class ZenModeFiltering {
? record.sbn.getNotification().extras : null; ? record.sbn.getNotification().extras : null;
} }
protected void recordCall(NotificationRecord record) {
REPEAT_CALLERS.recordCall(mContext, extras(record));
}
public boolean shouldIntercept(int zen, ZenModeConfig config, NotificationRecord record) { public boolean shouldIntercept(int zen, ZenModeConfig config, NotificationRecord record) {
if (isSystem(record)) { if (isSystem(record)) {
return false; return false;
@@ -233,28 +239,45 @@ public class ZenModeFiltering {
} }
private static class RepeatCallers { private static class RepeatCallers {
// Person : time
private final ArrayMap<String, Long> mCalls = new ArrayMap<>(); private final ArrayMap<String, Long> mCalls = new ArrayMap<>();
private int mThresholdMinutes; private int mThresholdMinutes;
private synchronized void recordCall(Context context, Bundle extras) {
setThresholdMinutes(context);
if (mThresholdMinutes <= 0 || extras == null) return;
final String peopleString = peopleString(extras);
if (peopleString == null) return;
final long now = System.currentTimeMillis();
cleanUp(mCalls, now);
mCalls.put(peopleString, now);
}
private synchronized boolean isRepeat(Context context, Bundle extras) { private synchronized boolean isRepeat(Context context, Bundle extras) {
if (mThresholdMinutes <= 0) { setThresholdMinutes(context);
mThresholdMinutes = context.getResources().getInteger(com.android.internal.R.integer
.config_zen_repeat_callers_threshold);
}
if (mThresholdMinutes <= 0 || extras == null) return false; if (mThresholdMinutes <= 0 || extras == null) return false;
final String peopleString = peopleString(extras); final String peopleString = peopleString(extras);
if (peopleString == null) return false; if (peopleString == null) return false;
final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
final int N = mCalls.size(); cleanUp(mCalls, now);
return mCalls.containsKey(peopleString);
}
private synchronized void cleanUp(ArrayMap<String, Long> calls, long now) {
final int N = calls.size();
for (int i = N - 1; i >= 0; i--) { for (int i = N - 1; i >= 0; i--) {
final long time = mCalls.valueAt(i); final long time = mCalls.valueAt(i);
if (time > now || (now - time) > mThresholdMinutes * 1000 * 60) { if (time > now || (now - time) > mThresholdMinutes * 1000 * 60) {
mCalls.removeAt(i); calls.removeAt(i);
} }
} }
final boolean isRepeat = mCalls.containsKey(peopleString); }
mCalls.put(peopleString, now);
return isRepeat; private void setThresholdMinutes(Context context) {
if (mThresholdMinutes <= 0) {
mThresholdMinutes = context.getResources().getInteger(com.android.internal.R.integer
.config_zen_repeat_callers_threshold);
}
} }
private static String peopleString(Bundle extras) { private static String peopleString(Bundle extras) {

View File

@@ -139,8 +139,7 @@ public class ZenModeHelper {
ValidateNotificationPeople validator, int contactsTimeoutMs, float timeoutAffinity) { ValidateNotificationPeople validator, int contactsTimeoutMs, float timeoutAffinity) {
synchronized (mConfig) { synchronized (mConfig) {
return ZenModeFiltering.matchesCallFilter(mContext, mZenMode, mConfig, userHandle, return ZenModeFiltering.matchesCallFilter(mContext, mZenMode, mConfig, userHandle,
extras, extras, validator, contactsTimeoutMs, timeoutAffinity);
validator, contactsTimeoutMs, timeoutAffinity);
} }
} }
@@ -148,6 +147,10 @@ public class ZenModeHelper {
return mFiltering.isCall(record); return mFiltering.isCall(record);
} }
public void recordCaller(NotificationRecord record) {
mFiltering.recordCall(record);
}
public boolean shouldIntercept(NotificationRecord record) { public boolean shouldIntercept(NotificationRecord record) {
synchronized (mConfig) { synchronized (mConfig) {
return mFiltering.shouldIntercept(mZenMode, mConfig, record); return mFiltering.shouldIntercept(mZenMode, mConfig, record);