Silence notifications that are manually unsnoozed
Test: atest Bug: 149486431 Change-Id: I7d11859210f6000120b2c51dc33da3d0928fb22e
This commit is contained in:
@@ -2068,19 +2068,16 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
SnoozeHelper snoozeHelper = new SnoozeHelper(getContext(), new SnoozeHelper.Callback() {
|
||||
@Override
|
||||
public void repost(int userId, NotificationRecord r) {
|
||||
try {
|
||||
if (DBG) {
|
||||
Slog.d(TAG, "Reposting " + r.getKey());
|
||||
}
|
||||
enqueueNotificationInternal(r.getSbn().getPackageName(), r.getSbn().getOpPkg(),
|
||||
r.getSbn().getUid(), r.getSbn().getInitialPid(), r.getSbn().getTag(),
|
||||
r.getSbn().getId(), r.getSbn().getNotification(), userId);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "Cannot un-snooze notification", e);
|
||||
SnoozeHelper snoozeHelper = new SnoozeHelper(getContext(), (userId, r, muteOnReturn) -> {
|
||||
try {
|
||||
if (DBG) {
|
||||
Slog.d(TAG, "Reposting " + r.getKey());
|
||||
}
|
||||
enqueueNotificationInternal(r.getSbn().getPackageName(), r.getSbn().getOpPkg(),
|
||||
r.getSbn().getUid(), r.getSbn().getInitialPid(), r.getSbn().getTag(),
|
||||
r.getSbn().getId(), r.getSbn().getNotification(), userId, true);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "Cannot un-snooze notification", e);
|
||||
}
|
||||
}, mUserProfiles);
|
||||
|
||||
@@ -3983,7 +3980,7 @@ public class NotificationManagerService extends SystemService {
|
||||
synchronized (mNotificationLock) {
|
||||
final ManagedServiceInfo info =
|
||||
mAssistants.checkServiceTokenLocked(token);
|
||||
unsnoozeNotificationInt(key, info);
|
||||
unsnoozeNotificationInt(key, info, false);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
@@ -4006,7 +4003,7 @@ public class NotificationManagerService extends SystemService {
|
||||
if (!info.isSystem) {
|
||||
throw new SecurityException("Not allowed to unsnooze before deadline");
|
||||
}
|
||||
unsnoozeNotificationInt(key, info);
|
||||
unsnoozeNotificationInt(key, info, true);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
@@ -5525,6 +5522,13 @@ public class NotificationManagerService extends SystemService {
|
||||
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
|
||||
final int callingPid, final String tag, final int id, final Notification notification,
|
||||
int incomingUserId) {
|
||||
enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, notification,
|
||||
incomingUserId, false);
|
||||
}
|
||||
|
||||
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
|
||||
final int callingPid, final String tag, final int id, final Notification notification,
|
||||
int incomingUserId, boolean postSilently) {
|
||||
if (DBG) {
|
||||
Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
|
||||
+ " notification=" + notification);
|
||||
@@ -5605,6 +5609,7 @@ public class NotificationManagerService extends SystemService {
|
||||
user, null, System.currentTimeMillis());
|
||||
final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
|
||||
r.setIsAppImportanceLocked(mPreferencesHelper.getIsAppImportanceLocked(pkg, callingUid));
|
||||
r.setPostSilently(postSilently);
|
||||
|
||||
if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
|
||||
final boolean fgServiceShown = channel.isFgServiceShown();
|
||||
@@ -7040,6 +7045,11 @@ public class NotificationManagerService extends SystemService {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Suppressed because a user manually unsnoozed something (or similar)
|
||||
if (record.shouldPostSilently()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// muted by listener
|
||||
final String disableEffects = disableNotificationEffects(record);
|
||||
if (disableEffects != null) {
|
||||
@@ -8054,13 +8064,13 @@ public class NotificationManagerService extends SystemService {
|
||||
mHandler.post(new SnoozeNotificationRunnable(key, duration, snoozeCriterionId));
|
||||
}
|
||||
|
||||
void unsnoozeNotificationInt(String key, ManagedServiceInfo listener) {
|
||||
void unsnoozeNotificationInt(String key, ManagedServiceInfo listener, boolean muteOnReturn) {
|
||||
String listenerName = listener == null ? null : listener.component.toShortString();
|
||||
if (DBG) {
|
||||
Slog.d(TAG, String.format("unsnooze event(%s, %s)", key, listenerName));
|
||||
}
|
||||
mSnoozeHelper.cleanupPersistedContext(key);
|
||||
mSnoozeHelper.repost(key);
|
||||
mSnoozeHelper.repost(key, muteOnReturn);
|
||||
handleSavePolicyFile();
|
||||
}
|
||||
|
||||
|
||||
@@ -187,6 +187,7 @@ public final class NotificationRecord {
|
||||
private boolean mSuggestionsGeneratedByAssistant;
|
||||
private boolean mEditChoicesBeforeSending;
|
||||
private boolean mHasSeenSmartReplies;
|
||||
private boolean mPostSilently;
|
||||
/**
|
||||
* Whether this notification (and its channels) should be considered user locked. Used in
|
||||
* conjunction with user sentiment calculation.
|
||||
@@ -856,6 +857,17 @@ public final class NotificationRecord {
|
||||
return mHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of all alerting information on the channel and notification. Used when notifications
|
||||
* are reposted in response to direct user action and thus don't need to alert.
|
||||
*/
|
||||
public void setPostSilently(boolean postSilently) {
|
||||
mPostSilently = postSilently;
|
||||
}
|
||||
|
||||
public boolean shouldPostSilently() {
|
||||
return mPostSilently;
|
||||
}
|
||||
|
||||
public void setSuppressedVisualEffects(int effects) {
|
||||
mSuppressedVisualEffects = effects;
|
||||
|
||||
@@ -332,14 +332,14 @@ public class SnoozeHelper {
|
||||
records.put(record.getKey(), record);
|
||||
}
|
||||
|
||||
protected void repost(String key) {
|
||||
protected void repost(String key, boolean muteOnReturn) {
|
||||
Integer userId = mUsers.get(key);
|
||||
if (userId != null) {
|
||||
repost(key, userId);
|
||||
repost(key, userId, muteOnReturn);
|
||||
}
|
||||
}
|
||||
|
||||
protected void repost(String key, int userId) {
|
||||
protected void repost(String key, int userId, boolean muteOnReturn) {
|
||||
final String pkg = mPackages.remove(key);
|
||||
ArrayMap<String, NotificationRecord> records =
|
||||
mSnoozedNotifications.get(getPkgKey(userId, pkg));
|
||||
@@ -356,7 +356,7 @@ public class SnoozeHelper {
|
||||
MetricsLogger.action(record.getLogMaker()
|
||||
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
|
||||
.setType(MetricsProto.MetricsEvent.TYPE_OPEN));
|
||||
mCallback.repost(userId, record);
|
||||
mCallback.repost(userId, record, muteOnReturn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +388,7 @@ public class SnoozeHelper {
|
||||
MetricsLogger.action(record.getLogMaker()
|
||||
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
|
||||
.setType(MetricsProto.MetricsEvent.TYPE_OPEN));
|
||||
mCallback.repost(userId, record);
|
||||
mCallback.repost(userId, record, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -601,7 +601,7 @@ public class SnoozeHelper {
|
||||
}
|
||||
|
||||
protected interface Callback {
|
||||
void repost(int userId, NotificationRecord r);
|
||||
void repost(int userId, NotificationRecord r, boolean muteOnReturn);
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@@ -612,7 +612,7 @@ public class SnoozeHelper {
|
||||
}
|
||||
if (REPOST_ACTION.equals(intent.getAction())) {
|
||||
repost(intent.getStringExtra(EXTRA_KEY), intent.getIntExtra(EXTRA_USER_ID,
|
||||
UserHandle.USER_SYSTEM));
|
||||
UserHandle.USER_SYSTEM), false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -845,6 +845,18 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
|
||||
assertNotEquals(-1, r.getLastAudiblyAlertedMs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostSilently() throws Exception {
|
||||
NotificationRecord r = getBuzzyNotification();
|
||||
r.setPostSilently(true);
|
||||
|
||||
mService.buzzBeepBlinkLocked(r);
|
||||
|
||||
verifyNeverBeep();
|
||||
assertFalse(r.isInterruptive());
|
||||
assertEquals(-1, r.getLastAudiblyAlertedMs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGroupAlertSummarySilenceChild() throws Exception {
|
||||
NotificationRecord child = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY);
|
||||
|
||||
@@ -22,6 +22,7 @@ import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
@@ -363,8 +364,8 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
||||
|
||||
mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), "one", 1);
|
||||
|
||||
mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
|
||||
verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r);
|
||||
mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM, false);
|
||||
verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -374,8 +375,8 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
||||
NotificationRecord r2 = getNotificationRecord("pkg", 2, "one", UserHandle.ALL);
|
||||
mSnoozeHelper.snooze(r2, 1000);
|
||||
reset(mAm);
|
||||
mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
|
||||
mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM, false);
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
|
||||
ArgumentCaptor<PendingIntent> captor = ArgumentCaptor.forClass(PendingIntent.class);
|
||||
verify(mAm).cancel(captor.capture());
|
||||
assertEquals(r.getKey(), captor.getValue().getIntent().getStringExtra(EXTRA_KEY));
|
||||
@@ -388,8 +389,8 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
||||
NotificationRecord r2 = getNotificationRecord("pkg", 2, "one", UserHandle.ALL);
|
||||
mSnoozeHelper.snooze(r2, 1000);
|
||||
reset(mAm);
|
||||
mSnoozeHelper.repost(r.getKey());
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
|
||||
mSnoozeHelper.repost(r.getKey(), false);
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
|
||||
verify(mAm).cancel(any(PendingIntent.class));
|
||||
}
|
||||
|
||||
@@ -400,10 +401,10 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
||||
r.getNotification().category = "NEW CATEGORY";
|
||||
|
||||
mSnoozeHelper.update(UserHandle.USER_SYSTEM, r);
|
||||
verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class));
|
||||
verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class), anyBoolean());
|
||||
|
||||
mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
|
||||
mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM, false);
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -420,12 +421,22 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
||||
mSnoozeHelper.update(UserHandle.USER_SYSTEM, r);
|
||||
|
||||
// verify callback is called when repost (snooze is expired)
|
||||
verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class));
|
||||
mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM);
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
|
||||
verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class), anyBoolean());
|
||||
mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM, false);
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
|
||||
assertFalse(r.isCanceled);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReport_passesFlag() throws Exception {
|
||||
// snooze a notification
|
||||
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
||||
mSnoozeHelper.snooze(r , 1000);
|
||||
|
||||
mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM, true);
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSnoozedBy() throws Exception {
|
||||
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
||||
@@ -523,7 +534,7 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
||||
mSnoozeHelper.snooze(r2, 1000);
|
||||
mSnoozeHelper.repostGroupSummary("pkg", UserHandle.USER_SYSTEM, "group1");
|
||||
|
||||
verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r);
|
||||
verify(mCallback, never()).repost(eq(UserHandle.USER_SYSTEM), eq(r), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -542,8 +553,8 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
||||
|
||||
mSnoozeHelper.repostGroupSummary("pkg", UserHandle.USER_SYSTEM, r.getGroupKey());
|
||||
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r);
|
||||
verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r2);
|
||||
verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
|
||||
verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r2, false);
|
||||
|
||||
assertEquals(1, mSnoozeHelper.getSnoozed().size());
|
||||
assertEquals(1, mSnoozeHelper.getSnoozed(UserHandle.USER_SYSTEM, "pkg").size());
|
||||
|
||||
Reference in New Issue
Block a user