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

Commit a4e0a02f authored by Chloris Kuo's avatar Chloris Kuo
Browse files

Notification Intelligence Feedback UI Change

1. Remove OK button
2. If user taps Yes, closes dialog and if user taps No, redirects to
long press setting

Test: atest FeedbackInfoTest
Bug: 173460479
Change-Id: Idee79a0b28f480a51bf11bc0d31e836cf3eba9fc
parent aeca9585
Loading
Loading
Loading
Loading
+0 −20
Original line number Diff line number Diff line
@@ -109,24 +109,4 @@
            style="@style/TextAppearance.NotificationInfo.Button"/>
    </LinearLayout>

    <!-- Done button -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/notification_guts_button_spacing"
        android:layout_marginBottom="@dimen/notification_guts_button_spacing"
        android:gravity="end"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/ok"
            android:text="@string/feedback_ok"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:background="@drawable/ripple_drawable"
            android:minWidth="48dp"
            android:layout_marginStart="8dp"
            android:layout_marginEnd="-8dp"
            style="@style/TextAppearance.NotificationInfo.Button"/>
    </LinearLayout>
</com.android.systemui.statusbar.notification.row.FeedbackInfo>
+16 −14
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar.notification.row;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.service.notification.NotificationListenerService.Ranking.RANKING_DEMOTED;
import static android.service.notification.NotificationListenerService.Ranking.RANKING_PROMOTED;
import static android.service.notification.NotificationListenerService.Ranking.RANKING_UNCHANGED;

import android.annotation.SuppressLint;
import android.app.Notification;
@@ -43,6 +42,7 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -64,6 +64,9 @@ public class FeedbackInfo extends LinearLayout implements NotificationGuts.GutsC
    private NotificationEntryManager mNotificationEntryManager;
    private IStatusBarService mStatusBarService;
    private AssistantFeedbackController mFeedbackController;
    private NotificationGutsManager mNotificationGutsManager;
    private NotificationMenuRowPlugin mMenuRowPlugin;
    private ExpandableNotificationRow mExpandableNotificationRow;

    public FeedbackInfo(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -73,19 +76,21 @@ public class FeedbackInfo extends LinearLayout implements NotificationGuts.GutsC
            final PackageManager pm,
            final StatusBarNotification sbn,
            final NotificationEntry entry,
            final ExpandableNotificationRow row,
            final AssistantFeedbackController controller) {
        mPkg = sbn.getPackageName();
        mPm = pm;
        mEntry = entry;
        mExpandableNotificationRow = row;
        mRanking = entry.getRanking();
        mFeedbackController = controller;
        mAppName = mPkg;
        mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
        mStatusBarService = Dependency.get(IStatusBarService.class);
        mNotificationGutsManager = Dependency.get(NotificationGutsManager.class);

        bindHeader();
        bindPrompt();
        bindButton();
    }

    private void bindHeader() {
@@ -161,27 +166,24 @@ public class FeedbackInfo extends LinearLayout implements NotificationGuts.GutsC
        return sb.toString();
    }

    private void bindButton() {
        TextView ok = findViewById(R.id.ok);
        ok.setOnClickListener(this::closeControls);
    }

    private void positiveFeedback(View v) {
        mGutsContainer.closeControls(v, false);
        handleFeedback(true);
    }

    private void negativeFeedback(View v) {
        mMenuRowPlugin = mExpandableNotificationRow.getProvider();
        NotificationMenuRowPlugin.MenuItem menuItem = null;
        if (mMenuRowPlugin != null) {
            menuItem = mMenuRowPlugin.getLongpressMenuItem(mContext);
        }

        mGutsContainer.closeControls(v, false);
        mNotificationGutsManager.openGuts(mExpandableNotificationRow, 0, 0, menuItem);
        handleFeedback(false);
    }

    private void handleFeedback(boolean positive) {
        TextView prompt = findViewById(R.id.prompt);
        prompt.setText(mContext.getString(R.string.feedback_response));
        TextView yes = findViewById(R.id.yes);
        yes.setVisibility(View.GONE);
        TextView no = findViewById(R.id.no);
        no.setVisibility(View.GONE);

        Bundle feedback = new Bundle();
        feedback.putBoolean(FEEDBACK_KEY, positive);
        sendFeedbackToAssistant(feedback);
+1 −1
Original line number Diff line number Diff line
@@ -324,7 +324,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
                userHandle.getIdentifier());

        if (mAssistantFeedbackController.showFeedbackIndicator(row.getEntry())) {
            feedbackInfo.bindGuts(pmUser, sbn, row.getEntry(), mAssistantFeedbackController);
            feedbackInfo.bindGuts(pmUser, sbn, row.getEntry(), row, mAssistantFeedbackController);
        }
    }

+51 −22
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
@@ -56,6 +55,7 @@ import android.widget.TextView;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -65,8 +65,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;

import java.util.concurrent.CountDownLatch;
import org.mockito.MockitoAnnotations;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -78,18 +77,24 @@ public class FeedbackInfoTest extends SysuiTestCase {
    private FeedbackInfo mFeedbackInfo;
    private final PackageManager mMockPackageManager = mock(PackageManager.class);
    private final NotificationGuts mGutsParent = mock(NotificationGuts.class);
    private final ExpandableNotificationRow mMockNotificationRow =
            mock(ExpandableNotificationRow.class);
    private StatusBarNotification mSbn;

    @Mock
    private NotificationEntryManager mNotificationEntryManager;
    @Mock
    private IStatusBarService mStatusBarService;
    @Mock
    private NotificationGutsManager mNotificationGutsManager;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
        mDependency.injectTestDependency(IStatusBarService.class, mStatusBarService);
        mDependency.injectTestDependency(NotificationGutsManager.class, mNotificationGutsManager);

        // Inflate the layout
        final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
@@ -108,13 +113,14 @@ public class FeedbackInfoTest extends SysuiTestCase {

        mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
                new Notification(), UserHandle.CURRENT, null, 0);

    }

    @Test
    public void testBindNotification_SetsTextApplicationName() {
        when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
        mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(),
                mock(AssistantFeedbackController.class));
                mMockNotificationRow, mock(AssistantFeedbackController.class));
        final TextView textView = mFeedbackInfo.findViewById(R.id.pkg_name);
        assertTrue(textView.getText().toString().contains("App Name"));
    }
@@ -125,27 +131,16 @@ public class FeedbackInfoTest extends SysuiTestCase {
        when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
                .thenReturn(iconDrawable);
        mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(),
                mock(AssistantFeedbackController.class));
                mMockNotificationRow, mock(AssistantFeedbackController.class));
        final ImageView iconView = mFeedbackInfo.findViewById(R.id.pkg_icon);
        assertEquals(iconDrawable, iconView.getDrawable());
    }

    @Test
    public void testOk() {
        final CountDownLatch latch = new CountDownLatch(1);
        mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(),
                mock(AssistantFeedbackController.class));

        final View okButton = mFeedbackInfo.findViewById(R.id.ok);
        okButton.performClick();
        assertEquals(1, latch.getCount());
        verify(mGutsParent, times(1)).closeControls(any(), anyBoolean());
    }

    @Test
    public void testPrompt_silenced() {
        mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(IMPORTANCE_DEFAULT,
                IMPORTANCE_LOW, RANKING_UNCHANGED), mock(AssistantFeedbackController.class));
                IMPORTANCE_LOW, RANKING_UNCHANGED), mMockNotificationRow,
                mock(AssistantFeedbackController.class));
        TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
        assertEquals("This notification was silenced by the system. Was this correct?",
                prompt.getText());
@@ -154,7 +149,8 @@ public class FeedbackInfoTest extends SysuiTestCase {
    @Test
    public void testPrompt_promoted_importance() {
        mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(IMPORTANCE_DEFAULT,
                IMPORTANCE_HIGH, RANKING_UNCHANGED), mock(AssistantFeedbackController.class));
                IMPORTANCE_HIGH, RANKING_UNCHANGED), mMockNotificationRow,
                mock(AssistantFeedbackController.class));
        TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
        assertEquals("This notification was promoted by the system. Was this correct?",
                prompt.getText());
@@ -163,7 +159,8 @@ public class FeedbackInfoTest extends SysuiTestCase {
    @Test
    public void testPrompt_promoted_ranking() {
        mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(IMPORTANCE_DEFAULT,
                IMPORTANCE_DEFAULT, RANKING_PROMOTED), mock(AssistantFeedbackController.class));
                IMPORTANCE_DEFAULT, RANKING_PROMOTED), mMockNotificationRow,
                mock(AssistantFeedbackController.class));
        TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
        assertEquals("This notification was promoted by the system. Was this correct?",
                prompt.getText());
@@ -172,7 +169,8 @@ public class FeedbackInfoTest extends SysuiTestCase {
    @Test
    public void testPrompt_demoted_importance() {
        mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(IMPORTANCE_LOW,
                IMPORTANCE_MIN, RANKING_UNCHANGED), mock(AssistantFeedbackController.class));
                IMPORTANCE_MIN, RANKING_UNCHANGED), mMockNotificationRow,
                mock(AssistantFeedbackController.class));
        TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
        assertEquals("This notification was demoted by the system. Was this correct?",
                prompt.getText());
@@ -181,12 +179,43 @@ public class FeedbackInfoTest extends SysuiTestCase {
    @Test
    public void testPrompt_demoted_ranking() {
        mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(IMPORTANCE_DEFAULT,
                IMPORTANCE_DEFAULT, RANKING_DEMOTED), mock(AssistantFeedbackController.class));
                IMPORTANCE_DEFAULT, RANKING_DEMOTED), mMockNotificationRow,
                mock(AssistantFeedbackController.class));
        TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
        assertEquals("This notification was demoted by the system. Was this correct?",
                prompt.getText());
    }

    @Test
    public void testPositiveFeedback() {
        mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
                mock(AssistantFeedbackController.class));

        final View yes = mFeedbackInfo.findViewById(R.id.yes);
        yes.performClick();
        verify(mGutsParent, times(1)).closeControls(yes, false);
    }

    @Test
    public void testNegativeFeedback() {
        when(mNotificationGutsManager.openGuts(
                any(View.class),
                anyInt(),
                anyInt(),
                any(NotificationMenuRowPlugin.MenuItem.class)))
                .thenReturn(true);

        mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
                mock(AssistantFeedbackController.class));

        final View no = mFeedbackInfo.findViewById(R.id.no);
        no.performClick();
        verify(mGutsParent, times(1)).closeControls(no, false);
        verify(mNotificationGutsManager, times(1)).openGuts(
                eq(mMockNotificationRow), eq(0), eq(0),
                any());
    }

    private NotificationEntry getEntry(int oldImportance, int newImportance,
            int rankingAdjustment) {
        NotificationChannel channel = new NotificationChannel("id", "name", oldImportance);