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

Commit 1d958f8c authored by Dan Sandler's avatar Dan Sandler Committed by Daniel Sandler
Browse files

Temporary affordance for blocking helper

When a notification is flagged by NoMan as USER_SENTIMENT_NEGATIVE (odd,
since this is actually the system's sentiment), a small  icon will
appear that directs you to the notification settings.

Eventually the icon will be removed, and the settings (reworded to
explain that you seem not to like this kind of notification) will be
left behind in the shade.

Bug: 63095540
Test: runtest systemui
Change-Id: I8b815cd035e9730bbbf1d4a1be17db9d494111ed
parent 98fe2bca
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.util.Log;
import android.widget.RemoteViews;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;

import java.lang.annotation.Retention;
@@ -1543,7 +1544,11 @@ public abstract class NotificationListenerService extends Service {
            return mShowBadge;
        }

        private void populate(String key, int rank, boolean matchesInterruptionFilter,
        /**
         * @hide
         */
        @VisibleForTesting
        public void populate(String key, int rank, boolean matchesInterruptionFilter,
                int visibilityOverride, int suppressedVisualEffects, int importance,
                CharSequence explanation, String overrideGroupKey,
                NotificationChannel channel, ArrayList<String> overridePeople,
+12 −0
Original line number Diff line number Diff line
@@ -54,6 +54,18 @@
        android:paddingStart="8dp"
        />

    <ImageButton
        android:id="@+id/helper"
        android:layout_width="48dp"
        android:layout_height="@*android:dimen/notification_header_height"
        android:layout_gravity="top|end"
        android:layout_marginEnd="6dp"
        android:src="@drawable/ic_dnd"
        android:tint="#FF0000"
        android:background="@drawable/ripple_drawable"
        android:visibility="visible"
        />

    <ViewStub
        android:layout="@layout/notification_children_container"
        android:id="@+id/child_container_stub"
+15 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.util.FloatProperty;
@@ -173,6 +174,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    private FalsingManager mFalsingManager;
    private AboveShelfChangedListener mAboveShelfChangedListener;
    private HeadsUpManager mHeadsUpManager;
    private View mHelperButton;

    private boolean mJustClicked;
    private boolean mIconAnimationRunning;
@@ -387,6 +389,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        updateLimits();
        updateIconVisibilities();
        updateShelfIconColor();

        showBlockingHelper(mEntry.userSentiment ==
                NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
    }

    @VisibleForTesting
@@ -1318,6 +1323,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        requestLayout();
    }

    public void showBlockingHelper(boolean show) {
        mHelperButton.setVisibility(show ? View.VISIBLE : View.GONE);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
@@ -1325,6 +1334,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
        mLayouts = new NotificationContentView[] {mPrivateLayout, mPublicLayout};

        final NotificationGutsManager gutsMan = Dependency.get(NotificationGutsManager.class);
        mHelperButton = findViewById(R.id.helper);
        mHelperButton.setOnClickListener(view -> {
            doLongClickCallback();
        });

        for (NotificationContentView l : mLayouts) {
            l.setExpandClickListener(mExpandClickListener);
            l.setContainingNotification(this);
+3 −0
Original line number Diff line number Diff line
@@ -86,6 +86,8 @@ public class NotificationData {
        public RemoteViews cachedAmbientContentView;
        public CharSequence remoteInputText;
        public List<SnoozeCriterion> snoozeCriteria;
        public int userSentiment = Ranking.USER_SENTIMENT_NEUTRAL;

        private int mCachedContrastColor = COLOR_INVALID;
        private int mCachedContrastColorIsFor = COLOR_INVALID;
        private InflationTask mRunningTask = null;
@@ -463,6 +465,7 @@ public class NotificationData {
                    }
                    entry.channel = getChannel(entry.key);
                    entry.snoozeCriteria = getSnoozeCriteria(entry.key);
                    entry.userSentiment = mTmpRanking.getUserSentiment();
                }
            }
        }
+28 −0
Original line number Diff line number Diff line
@@ -32,11 +32,14 @@ import static org.mockito.Mockito.when;

import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationRankingUpdate;
import android.service.notification.StatusBarNotification;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
@@ -120,6 +123,23 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
        }
    }

    private void setUserSentiment(String key, int sentiment) {
        doAnswer(invocationOnMock -> {
            NotificationListenerService.Ranking ranking = (NotificationListenerService.Ranking)
                    invocationOnMock.getArguments()[1];
            ranking.populate(
                    key,
                    0,
                    false,
                    0,
                    0,
                    NotificationManager.IMPORTANCE_DEFAULT,
                    null, null,
                    null, null, null, true, sentiment);
            return true;
        }).when(mRankingMap).getRanking(eq(key), any(NotificationListenerService.Ranking.class));
    }

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
@@ -158,6 +178,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase {

        mEntryManager = new TestableNotificationEntryManager(mContext, mBarService);
        mEntryManager.setUpWithPresenter(mPresenter, mListContainer, mCallback, mHeadsUpManager);

        setUserSentiment(mEntry.key, NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL);
    }

    @Test
@@ -196,6 +218,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase {

        assertEquals(mEntryManager.getNotificationData().get(mSbn.getKey()), entry);
        assertNotNull(entry.row);
        assertEquals(mEntry.userSentiment,
                NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL);
    }

    @Test
@@ -204,6 +228,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase {

        mEntryManager.getNotificationData().add(mEntry);

        setUserSentiment(mEntry.key, NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);

        mHandler.post(() -> {
            mEntryManager.updateNotification(mSbn, mRankingMap);
        });
@@ -219,6 +245,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
        verify(mForegroundServiceController).updateNotification(eq(mSbn), anyInt());
        verify(mCallback).onNotificationUpdated(mSbn);
        assertNotNull(mEntry.row);
        assertEquals(mEntry.userSentiment,
                NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
    }

    @Test