blob: b81e048214634585ed78b3631097c39f75dacd82 [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;
Eliot Courtneye77edea2017-11-15 14:25:21 +090019import android.testing.AndroidTestingRunner;
20import android.testing.TestableLooper;
21
Brett Chabot84151d92019-02-27 15:37:59 -080022import androidx.test.filters.SmallTest;
23
Eliot Courtneye77edea2017-11-15 14:25:21 +090024import com.android.systemui.SysuiTestCase;
Kevina5ff1fa2018-08-21 16:35:48 -070025import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputActiveExtender;
26import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputHistoryExtender;
27import com.android.systemui.statusbar.NotificationRemoteInputManager.SmartReplyHistoryExtender;
Gus Prevas21437b32018-12-05 10:36:13 -050028import com.android.systemui.statusbar.notification.NotificationEntryManager;
Ned Burnsf81c4c42019-01-07 14:10:43 -050029import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Gus Prevas21437b32018-12-05 10:36:13 -050030import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
Gus Prevas772e5322018-12-21 16:22:16 -050031import com.android.systemui.statusbar.phone.ShadeController;
Kevina5ff1fa2018-08-21 16:35:48 -070032
Eliot Courtneye77edea2017-11-15 14:25:21 +090033import com.google.android.collect.Sets;
34
35import org.junit.Before;
36import org.junit.Test;
37import org.junit.runner.RunWith;
38import org.mockito.Mock;
39import org.mockito.MockitoAnnotations;
40
Gus Prevas772e5322018-12-21 16:22:16 -050041import dagger.Lazy;
42
Eliot Courtneye77edea2017-11-15 14:25:21 +090043@SmallTest
44@RunWith(AndroidTestingRunner.class)
45@TestableLooper.RunWithLooper
46public class NotificationRemoteInputManagerTest extends SysuiTestCase {
47 private static final String TEST_PACKAGE_NAME = "test";
48 private static final int TEST_UID = 0;
49
Eliot Courtneye77edea2017-11-15 14:25:21 +090050 @Mock private NotificationPresenter mPresenter;
51 @Mock private RemoteInputController.Delegate mDelegate;
Eliot Courtneye77edea2017-11-15 14:25:21 +090052 @Mock private NotificationRemoteInputManager.Callback mCallback;
53 @Mock private RemoteInputController mController;
Kevina5ff1fa2018-08-21 16:35:48 -070054 @Mock private SmartReplyController mSmartReplyController;
Eliot Courtneye77edea2017-11-15 14:25:21 +090055 @Mock private NotificationListenerService.RankingMap mRanking;
56 @Mock private ExpandableNotificationRow mRow;
57
Eliot Courtney8f56b0e2017-12-14 18:54:28 +090058 // Dependency mocks:
59 @Mock private NotificationEntryManager mEntryManager;
60 @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
61
Eliot Courtney8f56b0e2017-12-14 18:54:28 +090062 private TestableNotificationRemoteInputManager mRemoteInputManager;
63 private StatusBarNotification mSbn;
Ned Burnsf81c4c42019-01-07 14:10:43 -050064 private NotificationEntry mEntry;
Kevina5ff1fa2018-08-21 16:35:48 -070065 private RemoteInputHistoryExtender mRemoteInputHistoryExtender;
66 private SmartReplyHistoryExtender mSmartReplyHistoryExtender;
67 private RemoteInputActiveExtender mRemoteInputActiveExtender;
Eliot Courtney8f56b0e2017-12-14 18:54:28 +090068
Eliot Courtneye77edea2017-11-15 14:25:21 +090069 @Before
70 public void setUp() {
71 MockitoAnnotations.initMocks(this);
Eliot Courtneye77edea2017-11-15 14:25:21 +090072
Gus Prevas772e5322018-12-21 16:22:16 -050073 mRemoteInputManager = new TestableNotificationRemoteInputManager(mContext,
74 mLockscreenUserManager, mSmartReplyController, mEntryManager,
75 () -> mock(ShadeController.class),
76 Handler.createAsync(Looper.myLooper()));
Eliot Courtneye77edea2017-11-15 14:25:21 +090077 mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID,
78 0, new Notification(), UserHandle.CURRENT, null, 0);
Ned Burnsf81c4c42019-01-07 14:10:43 -050079 mEntry = new NotificationEntry(mSbn);
Evan Laird94492852018-10-25 13:43:01 -040080 mEntry.setRow(mRow);
Eliot Courtneye77edea2017-11-15 14:25:21 +090081
Gus Prevas21437b32018-12-05 10:36:13 -050082 mRemoteInputManager.setUpWithPresenterForTest(mCallback,
Eliot Courtney4a96b362017-12-14 19:38:52 +090083 mDelegate, mController);
Kevina5ff1fa2018-08-21 16:35:48 -070084 for (NotificationLifetimeExtender extender : mRemoteInputManager.getLifetimeExtenders()) {
85 extender.setCallback(
86 mock(NotificationLifetimeExtender.NotificationSafeToRemoveCallback.class));
87 }
Eliot Courtneye77edea2017-11-15 14:25:21 +090088 }
89
90 @Test
91 public void testPerformOnRemoveNotification() {
92 when(mController.isRemoteInputActive(mEntry)).thenReturn(true);
Gus Prevas772e5322018-12-21 16:22:16 -050093 mRemoteInputManager.onPerformRemoveNotification(mEntry, mSbn.getKey());
Eliot Courtneye77edea2017-11-15 14:25:21 +090094
95 verify(mController).removeRemoteInput(mEntry, null);
Eliot Courtneye77edea2017-11-15 14:25:21 +090096 }
97
98 @Test
Kevina5ff1fa2018-08-21 16:35:48 -070099 public void testShouldExtendLifetime_remoteInputActive() {
100 when(mController.isRemoteInputActive(mEntry)).thenReturn(true);
Eliot Courtneye77edea2017-11-15 14:25:21 +0900101
Kevina5ff1fa2018-08-21 16:35:48 -0700102 assertTrue(mRemoteInputActiveExtender.shouldExtendLifetime(mEntry));
Eliot Courtneye77edea2017-11-15 14:25:21 +0900103 }
104
Kevina5ff1fa2018-08-21 16:35:48 -0700105 @Test
106 public void testShouldExtendLifetime_isSpinning() {
107 NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY = true;
108 when(mController.isSpinning(mEntry.key)).thenReturn(true);
109
110 assertTrue(mRemoteInputHistoryExtender.shouldExtendLifetime(mEntry));
111 }
112
113 @Test
114 public void testShouldExtendLifetime_recentRemoteInput() {
115 NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY = true;
116 mEntry.lastRemoteInputSent = SystemClock.elapsedRealtime();
117
118 assertTrue(mRemoteInputHistoryExtender.shouldExtendLifetime(mEntry));
119 }
120
121 @Test
122 public void testShouldExtendLifetime_smartReplySending() {
123 NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY = true;
124 when(mSmartReplyController.isSendingSmartReply(mEntry.key)).thenReturn(true);
125
126 assertTrue(mSmartReplyHistoryExtender.shouldExtendLifetime(mEntry));
127 }
128
129 @Test
130 public void testNotificationWithRemoteInputActiveIsRemovedOnCollapse() {
Kevine9e938c2018-09-06 13:38:11 -0700131 mRemoteInputActiveExtender.setShouldManageLifetime(mEntry, true /* shouldManage */);
Kevina5ff1fa2018-08-21 16:35:48 -0700132
133 assertEquals(mRemoteInputManager.getEntriesKeptForRemoteInputActive(),
134 Sets.newArraySet(mEntry));
135
136 mRemoteInputManager.onPanelCollapsed();
137
138 assertTrue(mRemoteInputManager.getEntriesKeptForRemoteInputActive().isEmpty());
139 }
140
141 @Test
142 public void testRebuildWithRemoteInput_noExistingInputNoSpinner() {
143 StatusBarNotification newSbn =
144 mRemoteInputManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", false);
145 CharSequence[] messages = newSbn.getNotification().extras
146 .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
147 assertEquals(1, messages.length);
148 assertEquals("A Reply", messages[0]);
149 assertFalse(newSbn.getNotification().extras
150 .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
151 assertTrue(newSbn.getNotification().extras
152 .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false));
153 }
154
155 @Test
156 public void testRebuildWithRemoteInput_noExistingInputWithSpinner() {
157 StatusBarNotification newSbn =
158 mRemoteInputManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", true);
159 CharSequence[] messages = newSbn.getNotification().extras
160 .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
161 assertEquals(1, messages.length);
162 assertEquals("A Reply", messages[0]);
163 assertTrue(newSbn.getNotification().extras
164 .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
165 assertTrue(newSbn.getNotification().extras
166 .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false));
167 }
168
169 @Test
170 public void testRebuildWithRemoteInput_withExistingInput() {
171 // Setup a notification entry with 1 remote input.
172 StatusBarNotification newSbn =
173 mRemoteInputManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", false);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500174 NotificationEntry entry = new NotificationEntry(newSbn);
Kevina5ff1fa2018-08-21 16:35:48 -0700175
176 // Try rebuilding to add another reply.
177 newSbn = mRemoteInputManager.rebuildNotificationWithRemoteInput(entry, "Reply 2", true);
178 CharSequence[] messages = newSbn.getNotification().extras
179 .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
180 assertEquals(2, messages.length);
181 assertEquals("Reply 2", messages[0]);
182 assertEquals("A Reply", messages[1]);
183 }
184
185 @Test
186 public void testRebuildNotificationForCanceledSmartReplies() {
187 // Try rebuilding to remove spinner and hide buttons.
188 StatusBarNotification newSbn =
189 mRemoteInputManager.rebuildNotificationForCanceledSmartReplies(mEntry);
190 assertFalse(newSbn.getNotification().extras
191 .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
192 assertTrue(newSbn.getNotification().extras
193 .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false));
194 }
195
196
Eliot Courtneye77edea2017-11-15 14:25:21 +0900197 private class TestableNotificationRemoteInputManager extends NotificationRemoteInputManager {
198
Gus Prevas772e5322018-12-21 16:22:16 -0500199
200 TestableNotificationRemoteInputManager(Context context,
201 NotificationLockscreenUserManager lockscreenUserManager,
202 SmartReplyController smartReplyController,
203 NotificationEntryManager notificationEntryManager,
204 Lazy<ShadeController> shadeController,
205 Handler mainHandler) {
206 super(context, lockscreenUserManager, smartReplyController, notificationEntryManager,
207 shadeController, mainHandler);
Eliot Courtneye77edea2017-11-15 14:25:21 +0900208 }
209
Gus Prevas21437b32018-12-05 10:36:13 -0500210 public void setUpWithPresenterForTest(Callback callback,
Eliot Courtneye77edea2017-11-15 14:25:21 +0900211 RemoteInputController.Delegate delegate,
212 RemoteInputController controller) {
Gus Prevas21437b32018-12-05 10:36:13 -0500213 super.setUpWithCallback(callback, delegate);
Eliot Courtneye77edea2017-11-15 14:25:21 +0900214 mRemoteInputController = controller;
215 }
Kevina5ff1fa2018-08-21 16:35:48 -0700216
217 @Override
218 protected void addLifetimeExtenders() {
219 mRemoteInputActiveExtender = new RemoteInputActiveExtender();
220 mRemoteInputHistoryExtender = new RemoteInputHistoryExtender();
221 mSmartReplyHistoryExtender = new SmartReplyHistoryExtender();
222 mLifetimeExtenders.add(mRemoteInputHistoryExtender);
223 mLifetimeExtenders.add(mSmartReplyHistoryExtender);
224 mLifetimeExtenders.add(mRemoteInputActiveExtender);
225 }
Eliot Courtneye77edea2017-11-15 14:25:21 +0900226 }
227}