blob: c159516d5bde8c16bb9715255633936fa0e8c452 [file] [log] [blame]
Eliot Courtneye77edea2017-11-15 14:25:21 +09001package com.android.systemui.statusbar;
2
Kevina5ff1fa2018-08-21 16:35:48 -07003import static junit.framework.Assert.assertEquals;
Kevina5ff1fa2018-08-21 16:35:48 -07004import static junit.framework.Assert.assertFalse;
Gus Prevas21437b32018-12-05 10:36:13 -05005import static junit.framework.Assert.assertTrue;
Eliot Courtneye77edea2017-11-15 14:25:21 +09006
Kevina5ff1fa2018-08-21 16:35:48 -07007import static org.mockito.Mockito.mock;
Eliot Courtneye77edea2017-11-15 14:25:21 +09008import static org.mockito.Mockito.verify;
9import static org.mockito.Mockito.when;
10
11import android.app.Notification;
12import android.content.Context;
13import android.os.Handler;
14import android.os.Looper;
Kevina5ff1fa2018-08-21 16:35:48 -070015import android.os.SystemClock;
Eliot Courtneye77edea2017-11-15 14:25:21 +090016import android.os.UserHandle;
17import android.service.notification.NotificationListenerService;
18import android.service.notification.StatusBarNotification;
19import android.support.test.filters.SmallTest;
20import android.testing.AndroidTestingRunner;
21import android.testing.TestableLooper;
22
23import com.android.systemui.SysuiTestCase;
Kevina5ff1fa2018-08-21 16:35:48 -070024import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputActiveExtender;
25import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputHistoryExtender;
26import com.android.systemui.statusbar.NotificationRemoteInputManager.SmartReplyHistoryExtender;
Gus Prevas21437b32018-12-05 10:36:13 -050027import com.android.systemui.statusbar.notification.NotificationEntryManager;
Ned Burnsf81c4c42019-01-07 14:10:43 -050028import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Gus Prevas21437b32018-12-05 10:36:13 -050029import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
Gus Prevas772e5322018-12-21 16:22:16 -050030import com.android.systemui.statusbar.phone.ShadeController;
Kevina5ff1fa2018-08-21 16:35:48 -070031
Eliot Courtneye77edea2017-11-15 14:25:21 +090032import com.google.android.collect.Sets;
33
34import org.junit.Before;
35import org.junit.Test;
36import org.junit.runner.RunWith;
37import org.mockito.Mock;
38import org.mockito.MockitoAnnotations;
39
Gus Prevas772e5322018-12-21 16:22:16 -050040import dagger.Lazy;
41
Eliot Courtneye77edea2017-11-15 14:25:21 +090042@SmallTest
43@RunWith(AndroidTestingRunner.class)
44@TestableLooper.RunWithLooper
45public class NotificationRemoteInputManagerTest extends SysuiTestCase {
46 private static final String TEST_PACKAGE_NAME = "test";
47 private static final int TEST_UID = 0;
48
Eliot Courtneye77edea2017-11-15 14:25:21 +090049 @Mock private NotificationPresenter mPresenter;
50 @Mock private RemoteInputController.Delegate mDelegate;
Eliot Courtneye77edea2017-11-15 14:25:21 +090051 @Mock private NotificationRemoteInputManager.Callback mCallback;
52 @Mock private RemoteInputController mController;
Kevina5ff1fa2018-08-21 16:35:48 -070053 @Mock private SmartReplyController mSmartReplyController;
Eliot Courtneye77edea2017-11-15 14:25:21 +090054 @Mock private NotificationListenerService.RankingMap mRanking;
55 @Mock private ExpandableNotificationRow mRow;
56
Eliot Courtney8f56b0e2017-12-14 18:54:28 +090057 // Dependency mocks:
58 @Mock private NotificationEntryManager mEntryManager;
59 @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
60
Eliot Courtney8f56b0e2017-12-14 18:54:28 +090061 private TestableNotificationRemoteInputManager mRemoteInputManager;
62 private StatusBarNotification mSbn;
Ned Burnsf81c4c42019-01-07 14:10:43 -050063 private NotificationEntry mEntry;
Kevina5ff1fa2018-08-21 16:35:48 -070064 private RemoteInputHistoryExtender mRemoteInputHistoryExtender;
65 private SmartReplyHistoryExtender mSmartReplyHistoryExtender;
66 private RemoteInputActiveExtender mRemoteInputActiveExtender;
Eliot Courtney8f56b0e2017-12-14 18:54:28 +090067
Eliot Courtneye77edea2017-11-15 14:25:21 +090068 @Before
69 public void setUp() {
70 MockitoAnnotations.initMocks(this);
Eliot Courtneye77edea2017-11-15 14:25:21 +090071
Gus Prevas772e5322018-12-21 16:22:16 -050072 mRemoteInputManager = new TestableNotificationRemoteInputManager(mContext,
73 mLockscreenUserManager, mSmartReplyController, mEntryManager,
74 () -> mock(ShadeController.class),
75 Handler.createAsync(Looper.myLooper()));
Eliot Courtneye77edea2017-11-15 14:25:21 +090076 mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID,
77 0, new Notification(), UserHandle.CURRENT, null, 0);
Ned Burnsf81c4c42019-01-07 14:10:43 -050078 mEntry = new NotificationEntry(mSbn);
Evan Laird94492852018-10-25 13:43:01 -040079 mEntry.setRow(mRow);
Eliot Courtneye77edea2017-11-15 14:25:21 +090080
Gus Prevas21437b32018-12-05 10:36:13 -050081 mRemoteInputManager.setUpWithPresenterForTest(mCallback,
Eliot Courtney4a96b362017-12-14 19:38:52 +090082 mDelegate, mController);
Kevina5ff1fa2018-08-21 16:35:48 -070083 for (NotificationLifetimeExtender extender : mRemoteInputManager.getLifetimeExtenders()) {
84 extender.setCallback(
85 mock(NotificationLifetimeExtender.NotificationSafeToRemoveCallback.class));
86 }
Eliot Courtneye77edea2017-11-15 14:25:21 +090087 }
88
89 @Test
90 public void testPerformOnRemoveNotification() {
91 when(mController.isRemoteInputActive(mEntry)).thenReturn(true);
Gus Prevas772e5322018-12-21 16:22:16 -050092 mRemoteInputManager.onPerformRemoveNotification(mEntry, mSbn.getKey());
Eliot Courtneye77edea2017-11-15 14:25:21 +090093
94 verify(mController).removeRemoteInput(mEntry, null);
Eliot Courtneye77edea2017-11-15 14:25:21 +090095 }
96
97 @Test
Kevina5ff1fa2018-08-21 16:35:48 -070098 public void testShouldExtendLifetime_remoteInputActive() {
99 when(mController.isRemoteInputActive(mEntry)).thenReturn(true);
Eliot Courtneye77edea2017-11-15 14:25:21 +0900100
Kevina5ff1fa2018-08-21 16:35:48 -0700101 assertTrue(mRemoteInputActiveExtender.shouldExtendLifetime(mEntry));
Eliot Courtneye77edea2017-11-15 14:25:21 +0900102 }
103
Kevina5ff1fa2018-08-21 16:35:48 -0700104 @Test
105 public void testShouldExtendLifetime_isSpinning() {
106 NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY = true;
107 when(mController.isSpinning(mEntry.key)).thenReturn(true);
108
109 assertTrue(mRemoteInputHistoryExtender.shouldExtendLifetime(mEntry));
110 }
111
112 @Test
113 public void testShouldExtendLifetime_recentRemoteInput() {
114 NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY = true;
115 mEntry.lastRemoteInputSent = SystemClock.elapsedRealtime();
116
117 assertTrue(mRemoteInputHistoryExtender.shouldExtendLifetime(mEntry));
118 }
119
120 @Test
121 public void testShouldExtendLifetime_smartReplySending() {
122 NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY = true;
123 when(mSmartReplyController.isSendingSmartReply(mEntry.key)).thenReturn(true);
124
125 assertTrue(mSmartReplyHistoryExtender.shouldExtendLifetime(mEntry));
126 }
127
128 @Test
129 public void testNotificationWithRemoteInputActiveIsRemovedOnCollapse() {
Kevine9e938c2018-09-06 13:38:11 -0700130 mRemoteInputActiveExtender.setShouldManageLifetime(mEntry, true /* shouldManage */);
Kevina5ff1fa2018-08-21 16:35:48 -0700131
132 assertEquals(mRemoteInputManager.getEntriesKeptForRemoteInputActive(),
133 Sets.newArraySet(mEntry));
134
135 mRemoteInputManager.onPanelCollapsed();
136
137 assertTrue(mRemoteInputManager.getEntriesKeptForRemoteInputActive().isEmpty());
138 }
139
140 @Test
141 public void testRebuildWithRemoteInput_noExistingInputNoSpinner() {
142 StatusBarNotification newSbn =
143 mRemoteInputManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", false);
144 CharSequence[] messages = newSbn.getNotification().extras
145 .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
146 assertEquals(1, messages.length);
147 assertEquals("A Reply", messages[0]);
148 assertFalse(newSbn.getNotification().extras
149 .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
150 assertTrue(newSbn.getNotification().extras
151 .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false));
152 }
153
154 @Test
155 public void testRebuildWithRemoteInput_noExistingInputWithSpinner() {
156 StatusBarNotification newSbn =
157 mRemoteInputManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", true);
158 CharSequence[] messages = newSbn.getNotification().extras
159 .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
160 assertEquals(1, messages.length);
161 assertEquals("A Reply", messages[0]);
162 assertTrue(newSbn.getNotification().extras
163 .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
164 assertTrue(newSbn.getNotification().extras
165 .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false));
166 }
167
168 @Test
169 public void testRebuildWithRemoteInput_withExistingInput() {
170 // Setup a notification entry with 1 remote input.
171 StatusBarNotification newSbn =
172 mRemoteInputManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", false);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500173 NotificationEntry entry = new NotificationEntry(newSbn);
Kevina5ff1fa2018-08-21 16:35:48 -0700174
175 // Try rebuilding to add another reply.
176 newSbn = mRemoteInputManager.rebuildNotificationWithRemoteInput(entry, "Reply 2", true);
177 CharSequence[] messages = newSbn.getNotification().extras
178 .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
179 assertEquals(2, messages.length);
180 assertEquals("Reply 2", messages[0]);
181 assertEquals("A Reply", messages[1]);
182 }
183
184 @Test
185 public void testRebuildNotificationForCanceledSmartReplies() {
186 // Try rebuilding to remove spinner and hide buttons.
187 StatusBarNotification newSbn =
188 mRemoteInputManager.rebuildNotificationForCanceledSmartReplies(mEntry);
189 assertFalse(newSbn.getNotification().extras
190 .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
191 assertTrue(newSbn.getNotification().extras
192 .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false));
193 }
194
195
Eliot Courtneye77edea2017-11-15 14:25:21 +0900196 private class TestableNotificationRemoteInputManager extends NotificationRemoteInputManager {
197
Gus Prevas772e5322018-12-21 16:22:16 -0500198
199 TestableNotificationRemoteInputManager(Context context,
200 NotificationLockscreenUserManager lockscreenUserManager,
201 SmartReplyController smartReplyController,
202 NotificationEntryManager notificationEntryManager,
203 Lazy<ShadeController> shadeController,
204 Handler mainHandler) {
205 super(context, lockscreenUserManager, smartReplyController, notificationEntryManager,
206 shadeController, mainHandler);
Eliot Courtneye77edea2017-11-15 14:25:21 +0900207 }
208
Gus Prevas21437b32018-12-05 10:36:13 -0500209 public void setUpWithPresenterForTest(Callback callback,
Eliot Courtneye77edea2017-11-15 14:25:21 +0900210 RemoteInputController.Delegate delegate,
211 RemoteInputController controller) {
Gus Prevas21437b32018-12-05 10:36:13 -0500212 super.setUpWithCallback(callback, delegate);
Eliot Courtneye77edea2017-11-15 14:25:21 +0900213 mRemoteInputController = controller;
214 }
Kevina5ff1fa2018-08-21 16:35:48 -0700215
216 @Override
217 protected void addLifetimeExtenders() {
218 mRemoteInputActiveExtender = new RemoteInputActiveExtender();
219 mRemoteInputHistoryExtender = new RemoteInputHistoryExtender();
220 mSmartReplyHistoryExtender = new SmartReplyHistoryExtender();
221 mLifetimeExtenders.add(mRemoteInputHistoryExtender);
222 mLifetimeExtenders.add(mSmartReplyHistoryExtender);
223 mLifetimeExtenders.add(mRemoteInputActiveExtender);
224 }
Eliot Courtneye77edea2017-11-15 14:25:21 +0900225 }
226}