Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61b6eb91 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Updates to Adjustment.KEY_IMPORTANCE handling"

parents 24a5a5d1 27c0a96c
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -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";

+18 −5
Original line number Diff line number Diff line
@@ -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);
                    }
                }
@@ -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;
@@ -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);
@@ -4842,7 +4852,7 @@ public class NotificationManagerService extends SystemService {
                                | Notification.FLAG_NO_CLEAR;
                    }

                    applyZenModeLocked(r);
                    mRankingHelper.extractSignals(r);
                    mRankingHelper.sort(mNotificationList);

                    if (!r.isHidden()) {
@@ -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());
@@ -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);
@@ -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;
                }
+27 −18
Original line number Diff line number Diff line
@@ -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;
@@ -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);
@@ -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);
@@ -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();
    }

@@ -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;
    }

    /**
@@ -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";
        }
+57 −14
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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 =
@@ -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);
@@ -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)));

@@ -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)));

@@ -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)));

@@ -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
@@ -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());
@@ -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(
@@ -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);
@@ -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("",
+3 −0
Original line number Diff line number Diff line
@@ -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
@@ -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());
    }

@@ -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(