diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index d799721a27fa5..b299f353a55d9 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -139,6 +139,10 @@
10000
+
+ 60000
+
700
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 5613a6e42c2a9..a2796c66783fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -600,6 +600,7 @@ public abstract class BaseStatusBar extends SystemUI implements
}
mCurrentUserId = ActivityManager.getCurrentUser();
+ setHeadsUpUser(mCurrentUserId);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
@@ -662,7 +663,13 @@ public abstract class BaseStatusBar extends SystemUI implements
}
public void userSwitched(int newUserId) {
- // should be overridden
+ setHeadsUpUser(newUserId);
+ }
+
+ private void setHeadsUpUser(int newUserId) {
+ if (mHeadsUpNotificationView != null) {
+ mHeadsUpNotificationView.setUser(newUserId);
+ }
}
public boolean isHeadsUp(String key) {
@@ -2065,6 +2072,10 @@ public abstract class BaseStatusBar extends SystemUI implements
return false;
}
+ if (mHeadsUpNotificationView.isSnoozed(sbn.getPackageName())) {
+ return false;
+ }
+
Notification notification = sbn.getNotification();
// some predicates to make the boolean logic legible
boolean isNoisy = (notification.defaults & Notification.DEFAULT_SOUND) != 0
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index daabcbd4341ca..be7670d7c4cd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3181,6 +3181,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
@Override
public void userSwitched(int newUserId) {
+ super.userSwitched(newUserId);
if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
animateCollapsePanels();
updatePublicMode();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index 11ff272ce70c1..8933d00912d9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -18,8 +18,13 @@ package com.android.systemui.statusbar.policy;
import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.database.ContentObserver;
import android.graphics.Outline;
import android.graphics.Rect;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
@@ -39,17 +44,23 @@ import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import java.util.ArrayList;
+
public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback,
ViewTreeObserver.OnComputeInternalInsetsListener {
private static final String TAG = "HeadsUpNotificationView";
private static final boolean DEBUG = false;
private static final boolean SPEW = DEBUG;
+ private static final String SETTING_HEADS_UP_SNOOZE_LENGTH_MS = "heads_up_snooze_length_ms";
Rect mTmpRect = new Rect();
int[] mTmpTwoArray = new int[2];
private final int mTouchSensitivityDelay;
private final float mMaxAlpha = 1f;
+ private final ArrayMap mSnoozedPackages;
+ private final int mDefaultSnoozeLengthMs;
+
private SwipeHelper mSwipeHelper;
private EdgeSwipeHelper mEdgeSwipeHelper;
@@ -57,8 +68,11 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
private long mStartTouchTime;
private ViewGroup mContentHolder;
+ private int mSnoozeLengthMs;
+ private ContentObserver mSettingsObserver;
private NotificationData.Entry mHeadsUp;
+ private int mUser;
public HeadsUpNotificationView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -66,8 +80,12 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
public HeadsUpNotificationView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mTouchSensitivityDelay = getResources().getInteger(R.integer.heads_up_sensitivity_delay);
+ Resources resources = context.getResources();
+ mTouchSensitivityDelay = resources.getInteger(R.integer.heads_up_sensitivity_delay);
if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay);
+ mSnoozedPackages = new ArrayMap<>();
+ mDefaultSnoozeLengthMs = resources.getInteger(R.integer.heads_up_default_snooze_length_ms);
+ mSnoozeLengthMs = mDefaultSnoozeLengthMs;
}
public void updateResources() {
@@ -115,7 +133,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
mSwipeHelper.snapChild(mContentHolder, 1f);
- mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
+ mStartTouchTime = SystemClock.elapsedRealtime() + mTouchSensitivityDelay;
mHeadsUp.setInterruption();
@@ -166,6 +184,29 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
mHeadsUp = null;
}
+ public boolean isSnoozed(String packageName) {
+ final String key = snoozeKey(packageName, mUser);
+ Long snoozedUntil = mSnoozedPackages.get(key);
+ if (snoozedUntil != null) {
+ if (snoozedUntil > SystemClock.elapsedRealtime()) {
+ if (DEBUG) Log.v(TAG, key + " snoozed");
+ return true;
+ }
+ mSnoozedPackages.remove(packageName);
+ }
+ return false;
+ }
+
+ private void snooze() {
+ mSnoozedPackages.put(snoozeKey(mHeadsUp.notification.getPackageName(), mUser),
+ SystemClock.elapsedRealtime() + mSnoozeLengthMs);
+ releaseAndClose();
+ }
+
+ private static String snoozeKey(String packageName, int user) {
+ return user + "," + packageName;
+ }
+
public void releaseAndClose() {
release();
mBar.scheduleHeadsUpClose();
@@ -209,6 +250,24 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
mContentHolder = (ViewGroup) findViewById(R.id.content_holder);
mContentHolder.setOutlineProvider(CONTENT_HOLDER_OUTLINE_PROVIDER);
+ mSnoozeLengthMs = Settings.Global.getInt(mContext.getContentResolver(),
+ SETTING_HEADS_UP_SNOOZE_LENGTH_MS, mDefaultSnoozeLengthMs);
+ mSettingsObserver = new ContentObserver(getHandler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ final int packageSnoozeLengthMs = Settings.Global.getInt(
+ mContext.getContentResolver(), SETTING_HEADS_UP_SNOOZE_LENGTH_MS, -1);
+ if (packageSnoozeLengthMs > -1 && packageSnoozeLengthMs != mSnoozeLengthMs) {
+ mSnoozeLengthMs = packageSnoozeLengthMs;
+ if (DEBUG) Log.v(TAG, "mSnoozeLengthMs = " + mSnoozeLengthMs);
+ }
+ }
+ };
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(SETTING_HEADS_UP_SNOOZE_LENGTH_MS), false,
+ mSettingsObserver);
+ if (DEBUG) Log.v(TAG, "mSnoozeLengthMs = " + mSnoozeLengthMs);
+
if (mHeadsUp != null) {
// whoops, we're on already!
showNotification(mHeadsUp);
@@ -217,10 +276,15 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
getViewTreeObserver().addOnComputeInternalInsetsListener(this);
}
+ @Override
+ protected void onDetachedFromWindow() {
+ mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()");
- if (System.currentTimeMillis() < mStartTouchTime) {
+ if (SystemClock.elapsedRealtime() < mStartTouchTime) {
return true;
}
return mEdgeSwipeHelper.onInterceptTouchEvent(ev)
@@ -246,7 +310,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
@Override
public boolean onTouchEvent(MotionEvent ev) {
- if (System.currentTimeMillis() < mStartTouchTime) {
+ if (SystemClock.elapsedRealtime() < mStartTouchTime) {
return false;
}
mBar.resetHeadsUpDecayTimer();
@@ -370,6 +434,10 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
return mHeadsUp == null ? null : mHeadsUp.notification.getKey();
}
+ public void setUser(int user) {
+ mUser = user;
+ }
+
private class EdgeSwipeHelper implements Gefingerpoken {
private static final boolean DEBUG_EDGE_SWIPE = false;
private final float mTouchSlop;
@@ -397,7 +465,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
final float daX = Math.abs(ev.getX() - mFirstX);
final float daY = Math.abs(dY);
if (!mConsuming && daX < daY && daY > mTouchSlop) {
- releaseAndClose();
+ snooze();
if (dY > 0) {
if (DEBUG_EDGE_SWIPE) Log.d(TAG, "found an open");
mBar.animateExpandNotificationsPanel();