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
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user