Merge "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"
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