Loading core/java/android/service/notification/Adjustment.java +12 −5 Original line number Diff line number Diff line Loading @@ -80,11 +80,18 @@ public final class Adjustment implements Parcelable { * Data type: int, one of importance values e.g. * {@link android.app.NotificationManager#IMPORTANCE_MIN}. * * If used from * {@link NotificationAssistantService#onNotificationEnqueued(StatusBarNotification)}, it can * block a notification from appearing or silence it. If used from * {@link NotificationAssistantService#adjustNotification(Adjustment)}, it can visually * demote a notification. * <p> If used from * {@link NotificationAssistantService#onNotificationEnqueued(StatusBarNotification)}, and * received before the notification is posted, it can block a notification from appearing or * silence it. Importance adjustments received too late from * {@link NotificationAssistantService#onNotificationEnqueued(StatusBarNotification)} will be * ignored. * </p> * <p>If used from * {@link NotificationAssistantService#adjustNotification(Adjustment)}, it can * visually demote or cancel a notification, but use this with care if they notification was * recently posted because the notification may already have made noise. * </p> */ public static final String KEY_IMPORTANCE = "key_importance"; Loading services/core/java/com/android/server/notification/NotificationManagerService.java +18 −5 Original line number Diff line number Diff line Loading @@ -3621,12 +3621,19 @@ public class NotificationManagerService extends SystemService { && mAssistants.isSameUser(token, r.getUserId())) { applyAdjustment(r, adjustment); r.applyAdjustments(); // importance is checked at the beginning of the // PostNotificationRunnable, before the signal extractors are run, so // calculate the final importance here r.calculateImportance(); foundEnqueued = true; break; } } if (!foundEnqueued) { // adjustment arrived too late to apply to enqueued; apply to posted // However, since the notification is now posted and may have alerted, // ignore any importance related adjustments adjustment.getSignals().remove(Adjustment.KEY_IMPORTANCE); applyAdjustmentFromAssistant(token, adjustment); } } Loading Loading @@ -3656,8 +3663,12 @@ public class NotificationManagerService extends SystemService { NotificationRecord r = mNotificationsByKey.get(adjustment.getKey()); if (r != null && mAssistants.isSameUser(token, r.getUserId())) { applyAdjustment(r, adjustment); r.applyImportanceFromAdjustments(); if (r.getImportance() == IMPORTANCE_NONE) { // If the assistant has blocked the notification, cancel it // This will trigger a sort, so we don't have to explicitly ask for // one here. if (adjustment.getSignals().containsKey(Adjustment.KEY_IMPORTANCE) && adjustment.getSignals().getInt(Adjustment.KEY_IMPORTANCE) == IMPORTANCE_NONE) { cancelNotificationsFromListener(token, new String[]{r.getKey()}); } else { needsSort = true; Loading Loading @@ -4758,7 +4769,6 @@ public class NotificationManagerService extends SystemService { enqueueStatus); } mRankingHelper.extractSignals(r); // tell the assistant service about the notification if (mAssistants.isEnabled()) { mAssistants.onNotificationEnqueuedLocked(r); Loading Loading @@ -4842,7 +4852,7 @@ public class NotificationManagerService extends SystemService { | Notification.FLAG_NO_CLEAR; } applyZenModeLocked(r); mRankingHelper.extractSignals(r); mRankingHelper.sort(mNotificationList); if (!r.isHidden()) { Loading Loading @@ -5627,6 +5637,7 @@ public class NotificationManagerService extends SystemService { ArrayList<Integer> suppressVisuallyBefore = new ArrayList<>(N); ArrayList<ArrayList<Notification.Action>> systemSmartActionsBefore = new ArrayList<>(N); ArrayList<ArrayList<CharSequence>> smartRepliesBefore = new ArrayList<>(N); int[] importancesBefore = new int[N]; for (int i = 0; i < N; i++) { final NotificationRecord r = mNotificationList.get(i); orderBefore.add(r.getKey()); Loading @@ -5640,6 +5651,7 @@ public class NotificationManagerService extends SystemService { suppressVisuallyBefore.add(r.getSuppressedVisualEffects()); systemSmartActionsBefore.add(r.getSystemGeneratedSmartActions()); smartRepliesBefore.add(r.getSmartReplies()); importancesBefore[i] = r.getImportance(); mRankingHelper.extractSignals(r); } mRankingHelper.sort(mNotificationList); Loading @@ -5657,7 +5669,8 @@ public class NotificationManagerService extends SystemService { r.getSuppressedVisualEffects()) || !Objects.equals(systemSmartActionsBefore.get(i), r.getSystemGeneratedSmartActions()) || !Objects.equals(smartRepliesBefore.get(i), r.getSmartReplies())) { || !Objects.equals(smartRepliesBefore.get(i), r.getSmartReplies()) || importancesBefore[i] != r.getImportance()) { mHandler.scheduleSendRankingUpdate(); return; } Loading services/core/java/com/android/server/notification/NotificationRecord.java +27 −18 Original line number Diff line number Diff line Loading @@ -21,10 +21,8 @@ import static android.app.NotificationManager.IMPORTANCE_HIGH; import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_MIN; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; import static android.service.notification.NotificationListenerService.Ranking .USER_SENTIMENT_NEUTRAL; import static android.service.notification.NotificationListenerService.Ranking .USER_SENTIMENT_POSITIVE; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE; import android.annotation.Nullable; import android.app.ActivityManager; Loading Loading @@ -609,6 +607,17 @@ public final class NotificationRecord { mIsAppImportanceLocked, this.sbn.getNotification()); } public boolean hasAdjustment(String key) { synchronized (mAdjustments) { for (Adjustment adjustment : mAdjustments) { if (adjustment.getSignals().containsKey(key)) { return true; } } } return false; } public void addAdjustment(Adjustment adjustment) { synchronized (mAdjustments) { mAdjustments.add(adjustment); Loading Loading @@ -669,18 +678,6 @@ public final class NotificationRecord { .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_REPLIES, getSmartReplies().size())); } } applyImportanceFromAdjustments(); } } /** * Update importance from the adjustment. */ public void applyImportanceFromAdjustments() { synchronized (mAdjustments) { for (Adjustment adjustment : mAdjustments) { Bundle signals = adjustment.getSignals(); if (signals.containsKey(Adjustment.KEY_IMPORTANCE)) { int importance = signals.getInt(Adjustment.KEY_IMPORTANCE); importance = Math.max(IMPORTANCE_UNSPECIFIED, importance); Loading Loading @@ -752,6 +749,8 @@ public final class NotificationRecord { */ public void setSystemImportance(int importance) { mSystemImportance = importance; // System importance is only changed in enqueue, so it's ok for us to calculate the // importance directly instead of waiting for signal extractor. calculateImportance(); } Loading @@ -762,7 +761,16 @@ public final class NotificationRecord { */ public void setAssistantImportance(int importance) { mAssistantImportance = importance; calculateImportance(); // Unlike the system importance, the assistant importance can change on posted // notifications, so don't calculateImportance() here, but wait for the signal extractors. } /** * Returns the importance set by the assistant, or IMPORTANCE_UNSPECIFIED if the assistant * hasn't set it. */ public int getAssistantImportance() { return mAssistantImportance; } /** Loading @@ -774,7 +782,8 @@ public final class NotificationRecord { if (getChannel().hasUserSetImportance()) { mImportanceExplanation = "user"; } if (!getChannel().hasUserSetImportance() && mAssistantImportance != IMPORTANCE_UNSPECIFIED) { if (!getChannel().hasUserSetImportance() && mAssistantImportance != IMPORTANCE_UNSPECIFIED) { mImportance = mAssistantImportance; mImportanceExplanation = "asst"; } Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +57 −14 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREG import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; import static android.app.NotificationManager.EXTRA_BLOCKED_STATE; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_HIGH; import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_MAX; Loading Loading @@ -183,7 +184,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Resources mResources; private NotificationChannel mTestNotificationChannel = new NotificationChannel( TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT); TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); @Mock private NotificationListeners mListeners; @Mock private NotificationAssistants mAssistants; Loading Loading @@ -430,7 +431,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCreateNotificationChannels_SingleChannel() throws Exception { final NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel))); final NotificationChannel createdChannel = Loading @@ -452,9 +453,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCreateNotificationChannels_TwoChannels() throws Exception { final NotificationChannel channel1 = new NotificationChannel("id1", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id1", "name", IMPORTANCE_DEFAULT); final NotificationChannel channel2 = new NotificationChannel("id2", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id2", "name", IMPORTANCE_DEFAULT); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel1, channel2))); assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null); Loading @@ -465,7 +466,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance() throws Exception { final NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel))); Loading @@ -476,14 +477,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { new ParceledListSlice(Arrays.asList(dupeChannel))); final NotificationChannel createdChannel = mBinderService.getNotificationChannel(PKG, "id"); assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance()); assertEquals(IMPORTANCE_DEFAULT, createdChannel.getImportance()); } @Test public void testCreateNotificationChannels_SecondCreateAllowedToDowngradeImportance() throws Exception { final NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel))); Loading @@ -501,7 +502,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated() throws Exception { final NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel))); Loading @@ -524,14 +525,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond() throws Exception { final NotificationChannel channel1 = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); final NotificationChannel channel2 = new NotificationChannel("id", "name", IMPORTANCE_HIGH); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel1, channel2))); final NotificationChannel createdChannel = mBinderService.getNotificationChannel(PKG, "id"); assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance()); assertEquals(IMPORTANCE_DEFAULT, createdChannel.getImportance()); } @Test Loading Loading @@ -756,13 +757,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testBlockedNotifications_blockedByAssistant() throws Exception { when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH); NotificationRecord r = generateNotificationRecord(channel); mService.addEnqueuedNotification(r); r.setAssistantImportance(IMPORTANCE_NONE); Bundle bundle = new Bundle(); bundle.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE); Adjustment adjustment = new Adjustment( r.sbn.getPackageName(), r.getKey(), bundle, "", r.getUser().getIdentifier()); mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); NotificationManagerService.PostNotificationRunnable runnable = mService.new PostNotificationRunnable(r.getKey()); Loading Loading @@ -2617,7 +2623,7 @@ try { } @Test public void testAssistantIBlockingTriggersCancel() throws Exception { public void testAssistantBlockingTriggersCancel() throws Exception { final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); mService.addNotification(r); NotificationManagerService.WorkerHandler handler = mock( Loading Loading @@ -2656,6 +2662,43 @@ try { assertEquals(USER_SENTIMENT_NEGATIVE, r.getUserSentiment()); } @Test public void testApplyEnqueuedAdjustmentFromAssistant_importance_onTime() throws Exception { final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); mService.addEnqueuedNotification(r); NotificationManagerService.WorkerHandler handler = mock( NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW); Adjustment adjustment = new Adjustment( r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier()); mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); assertEquals(IMPORTANCE_LOW, r.getImportance()); } @Test public void testApplyEnqueuedAdjustmentFromAssistant_importance_tooLate() throws Exception { final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); mService.addNotification(r); NotificationManagerService.WorkerHandler handler = mock( NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW); Adjustment adjustment = new Adjustment( r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier()); mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); assertEquals(IMPORTANCE_DEFAULT, r.getImportance()); assertFalse(r.hasAdjustment(Adjustment.KEY_IMPORTANCE)); } @Test public void testApplyEnqueuedAdjustmentFromAssistant_crossUser() throws Exception { final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); Loading Loading @@ -2856,7 +2899,7 @@ try { @Test public void updateUriPermissions_update() throws Exception { NotificationChannel c = new NotificationChannel( TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT); TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); c.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT); Message message1 = new Message("", 0, ""); message1.setData("", Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java +3 −0 Original line number Diff line number Diff line Loading @@ -760,6 +760,7 @@ public class NotificationRecordTest extends UiServiceTestCase { NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel); record.setAssistantImportance(IMPORTANCE_LOW); record.calculateImportance(); assertEquals(IMPORTANCE_LOW, record.getImportance()); // assistant ignored if user expressed preference Loading @@ -767,6 +768,7 @@ public class NotificationRecordTest extends UiServiceTestCase { channel.lockFields(USER_LOCKED_IMPORTANCE); record.setAssistantImportance(IMPORTANCE_LOW); record.calculateImportance(); assertEquals(channel.getImportance(), record.getImportance()); } Loading @@ -779,6 +781,7 @@ public class NotificationRecordTest extends UiServiceTestCase { NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel); record.setAssistantImportance(IMPORTANCE_LOW); record.calculateImportance(); assertEquals(IMPORTANCE_LOW, record.getImportance()); record.updateNotificationChannel( Loading Loading
core/java/android/service/notification/Adjustment.java +12 −5 Original line number Diff line number Diff line Loading @@ -80,11 +80,18 @@ public final class Adjustment implements Parcelable { * Data type: int, one of importance values e.g. * {@link android.app.NotificationManager#IMPORTANCE_MIN}. * * If used from * {@link NotificationAssistantService#onNotificationEnqueued(StatusBarNotification)}, it can * block a notification from appearing or silence it. If used from * {@link NotificationAssistantService#adjustNotification(Adjustment)}, it can visually * demote a notification. * <p> If used from * {@link NotificationAssistantService#onNotificationEnqueued(StatusBarNotification)}, and * received before the notification is posted, it can block a notification from appearing or * silence it. Importance adjustments received too late from * {@link NotificationAssistantService#onNotificationEnqueued(StatusBarNotification)} will be * ignored. * </p> * <p>If used from * {@link NotificationAssistantService#adjustNotification(Adjustment)}, it can * visually demote or cancel a notification, but use this with care if they notification was * recently posted because the notification may already have made noise. * </p> */ public static final String KEY_IMPORTANCE = "key_importance"; Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +18 −5 Original line number Diff line number Diff line Loading @@ -3621,12 +3621,19 @@ public class NotificationManagerService extends SystemService { && mAssistants.isSameUser(token, r.getUserId())) { applyAdjustment(r, adjustment); r.applyAdjustments(); // importance is checked at the beginning of the // PostNotificationRunnable, before the signal extractors are run, so // calculate the final importance here r.calculateImportance(); foundEnqueued = true; break; } } if (!foundEnqueued) { // adjustment arrived too late to apply to enqueued; apply to posted // However, since the notification is now posted and may have alerted, // ignore any importance related adjustments adjustment.getSignals().remove(Adjustment.KEY_IMPORTANCE); applyAdjustmentFromAssistant(token, adjustment); } } Loading Loading @@ -3656,8 +3663,12 @@ public class NotificationManagerService extends SystemService { NotificationRecord r = mNotificationsByKey.get(adjustment.getKey()); if (r != null && mAssistants.isSameUser(token, r.getUserId())) { applyAdjustment(r, adjustment); r.applyImportanceFromAdjustments(); if (r.getImportance() == IMPORTANCE_NONE) { // If the assistant has blocked the notification, cancel it // This will trigger a sort, so we don't have to explicitly ask for // one here. if (adjustment.getSignals().containsKey(Adjustment.KEY_IMPORTANCE) && adjustment.getSignals().getInt(Adjustment.KEY_IMPORTANCE) == IMPORTANCE_NONE) { cancelNotificationsFromListener(token, new String[]{r.getKey()}); } else { needsSort = true; Loading Loading @@ -4758,7 +4769,6 @@ public class NotificationManagerService extends SystemService { enqueueStatus); } mRankingHelper.extractSignals(r); // tell the assistant service about the notification if (mAssistants.isEnabled()) { mAssistants.onNotificationEnqueuedLocked(r); Loading Loading @@ -4842,7 +4852,7 @@ public class NotificationManagerService extends SystemService { | Notification.FLAG_NO_CLEAR; } applyZenModeLocked(r); mRankingHelper.extractSignals(r); mRankingHelper.sort(mNotificationList); if (!r.isHidden()) { Loading Loading @@ -5627,6 +5637,7 @@ public class NotificationManagerService extends SystemService { ArrayList<Integer> suppressVisuallyBefore = new ArrayList<>(N); ArrayList<ArrayList<Notification.Action>> systemSmartActionsBefore = new ArrayList<>(N); ArrayList<ArrayList<CharSequence>> smartRepliesBefore = new ArrayList<>(N); int[] importancesBefore = new int[N]; for (int i = 0; i < N; i++) { final NotificationRecord r = mNotificationList.get(i); orderBefore.add(r.getKey()); Loading @@ -5640,6 +5651,7 @@ public class NotificationManagerService extends SystemService { suppressVisuallyBefore.add(r.getSuppressedVisualEffects()); systemSmartActionsBefore.add(r.getSystemGeneratedSmartActions()); smartRepliesBefore.add(r.getSmartReplies()); importancesBefore[i] = r.getImportance(); mRankingHelper.extractSignals(r); } mRankingHelper.sort(mNotificationList); Loading @@ -5657,7 +5669,8 @@ public class NotificationManagerService extends SystemService { r.getSuppressedVisualEffects()) || !Objects.equals(systemSmartActionsBefore.get(i), r.getSystemGeneratedSmartActions()) || !Objects.equals(smartRepliesBefore.get(i), r.getSmartReplies())) { || !Objects.equals(smartRepliesBefore.get(i), r.getSmartReplies()) || importancesBefore[i] != r.getImportance()) { mHandler.scheduleSendRankingUpdate(); return; } Loading
services/core/java/com/android/server/notification/NotificationRecord.java +27 −18 Original line number Diff line number Diff line Loading @@ -21,10 +21,8 @@ import static android.app.NotificationManager.IMPORTANCE_HIGH; import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_MIN; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; import static android.service.notification.NotificationListenerService.Ranking .USER_SENTIMENT_NEUTRAL; import static android.service.notification.NotificationListenerService.Ranking .USER_SENTIMENT_POSITIVE; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE; import android.annotation.Nullable; import android.app.ActivityManager; Loading Loading @@ -609,6 +607,17 @@ public final class NotificationRecord { mIsAppImportanceLocked, this.sbn.getNotification()); } public boolean hasAdjustment(String key) { synchronized (mAdjustments) { for (Adjustment adjustment : mAdjustments) { if (adjustment.getSignals().containsKey(key)) { return true; } } } return false; } public void addAdjustment(Adjustment adjustment) { synchronized (mAdjustments) { mAdjustments.add(adjustment); Loading Loading @@ -669,18 +678,6 @@ public final class NotificationRecord { .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_REPLIES, getSmartReplies().size())); } } applyImportanceFromAdjustments(); } } /** * Update importance from the adjustment. */ public void applyImportanceFromAdjustments() { synchronized (mAdjustments) { for (Adjustment adjustment : mAdjustments) { Bundle signals = adjustment.getSignals(); if (signals.containsKey(Adjustment.KEY_IMPORTANCE)) { int importance = signals.getInt(Adjustment.KEY_IMPORTANCE); importance = Math.max(IMPORTANCE_UNSPECIFIED, importance); Loading Loading @@ -752,6 +749,8 @@ public final class NotificationRecord { */ public void setSystemImportance(int importance) { mSystemImportance = importance; // System importance is only changed in enqueue, so it's ok for us to calculate the // importance directly instead of waiting for signal extractor. calculateImportance(); } Loading @@ -762,7 +761,16 @@ public final class NotificationRecord { */ public void setAssistantImportance(int importance) { mAssistantImportance = importance; calculateImportance(); // Unlike the system importance, the assistant importance can change on posted // notifications, so don't calculateImportance() here, but wait for the signal extractors. } /** * Returns the importance set by the assistant, or IMPORTANCE_UNSPECIFIED if the assistant * hasn't set it. */ public int getAssistantImportance() { return mAssistantImportance; } /** Loading @@ -774,7 +782,8 @@ public final class NotificationRecord { if (getChannel().hasUserSetImportance()) { mImportanceExplanation = "user"; } if (!getChannel().hasUserSetImportance() && mAssistantImportance != IMPORTANCE_UNSPECIFIED) { if (!getChannel().hasUserSetImportance() && mAssistantImportance != IMPORTANCE_UNSPECIFIED) { mImportance = mAssistantImportance; mImportanceExplanation = "asst"; } Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +57 −14 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREG import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; import static android.app.NotificationManager.EXTRA_BLOCKED_STATE; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_HIGH; import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_MAX; Loading Loading @@ -183,7 +184,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Resources mResources; private NotificationChannel mTestNotificationChannel = new NotificationChannel( TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT); TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); @Mock private NotificationListeners mListeners; @Mock private NotificationAssistants mAssistants; Loading Loading @@ -430,7 +431,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCreateNotificationChannels_SingleChannel() throws Exception { final NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel))); final NotificationChannel createdChannel = Loading @@ -452,9 +453,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCreateNotificationChannels_TwoChannels() throws Exception { final NotificationChannel channel1 = new NotificationChannel("id1", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id1", "name", IMPORTANCE_DEFAULT); final NotificationChannel channel2 = new NotificationChannel("id2", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id2", "name", IMPORTANCE_DEFAULT); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel1, channel2))); assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null); Loading @@ -465,7 +466,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance() throws Exception { final NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel))); Loading @@ -476,14 +477,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { new ParceledListSlice(Arrays.asList(dupeChannel))); final NotificationChannel createdChannel = mBinderService.getNotificationChannel(PKG, "id"); assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance()); assertEquals(IMPORTANCE_DEFAULT, createdChannel.getImportance()); } @Test public void testCreateNotificationChannels_SecondCreateAllowedToDowngradeImportance() throws Exception { final NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel))); Loading @@ -501,7 +502,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated() throws Exception { final NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel))); Loading @@ -524,14 +525,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond() throws Exception { final NotificationChannel channel1 = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); new NotificationChannel("id", "name", IMPORTANCE_DEFAULT); final NotificationChannel channel2 = new NotificationChannel("id", "name", IMPORTANCE_HIGH); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(channel1, channel2))); final NotificationChannel createdChannel = mBinderService.getNotificationChannel(PKG, "id"); assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance()); assertEquals(IMPORTANCE_DEFAULT, createdChannel.getImportance()); } @Test Loading Loading @@ -756,13 +757,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testBlockedNotifications_blockedByAssistant() throws Exception { when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH); NotificationRecord r = generateNotificationRecord(channel); mService.addEnqueuedNotification(r); r.setAssistantImportance(IMPORTANCE_NONE); Bundle bundle = new Bundle(); bundle.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE); Adjustment adjustment = new Adjustment( r.sbn.getPackageName(), r.getKey(), bundle, "", r.getUser().getIdentifier()); mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); NotificationManagerService.PostNotificationRunnable runnable = mService.new PostNotificationRunnable(r.getKey()); Loading Loading @@ -2617,7 +2623,7 @@ try { } @Test public void testAssistantIBlockingTriggersCancel() throws Exception { public void testAssistantBlockingTriggersCancel() throws Exception { final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); mService.addNotification(r); NotificationManagerService.WorkerHandler handler = mock( Loading Loading @@ -2656,6 +2662,43 @@ try { assertEquals(USER_SENTIMENT_NEGATIVE, r.getUserSentiment()); } @Test public void testApplyEnqueuedAdjustmentFromAssistant_importance_onTime() throws Exception { final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); mService.addEnqueuedNotification(r); NotificationManagerService.WorkerHandler handler = mock( NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW); Adjustment adjustment = new Adjustment( r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier()); mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); assertEquals(IMPORTANCE_LOW, r.getImportance()); } @Test public void testApplyEnqueuedAdjustmentFromAssistant_importance_tooLate() throws Exception { final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); mService.addNotification(r); NotificationManagerService.WorkerHandler handler = mock( NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW); Adjustment adjustment = new Adjustment( r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier()); mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); assertEquals(IMPORTANCE_DEFAULT, r.getImportance()); assertFalse(r.hasAdjustment(Adjustment.KEY_IMPORTANCE)); } @Test public void testApplyEnqueuedAdjustmentFromAssistant_crossUser() throws Exception { final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); Loading Loading @@ -2856,7 +2899,7 @@ try { @Test public void updateUriPermissions_update() throws Exception { NotificationChannel c = new NotificationChannel( TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT); TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); c.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT); Message message1 = new Message("", 0, ""); message1.setData("", Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java +3 −0 Original line number Diff line number Diff line Loading @@ -760,6 +760,7 @@ public class NotificationRecordTest extends UiServiceTestCase { NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel); record.setAssistantImportance(IMPORTANCE_LOW); record.calculateImportance(); assertEquals(IMPORTANCE_LOW, record.getImportance()); // assistant ignored if user expressed preference Loading @@ -767,6 +768,7 @@ public class NotificationRecordTest extends UiServiceTestCase { channel.lockFields(USER_LOCKED_IMPORTANCE); record.setAssistantImportance(IMPORTANCE_LOW); record.calculateImportance(); assertEquals(channel.getImportance(), record.getImportance()); } Loading @@ -779,6 +781,7 @@ public class NotificationRecordTest extends UiServiceTestCase { NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel); record.setAssistantImportance(IMPORTANCE_LOW); record.calculateImportance(); assertEquals(IMPORTANCE_LOW, record.getImportance()); record.updateNotificationChannel( Loading