blob: 67f941301e5fa67365ed8b3fd9dbe8a00b4067ce [file] [log] [blame]
Kevin01a53cb2018-11-09 18:19:54 -08001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.statusbar.phone;
18
Julia Reynolds138111f2020-02-26 11:17:39 -050019import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
Kevin Han933dc7c2020-01-29 11:17:46 -080020import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP;
21
Kevin01a53cb2018-11-09 18:19:54 -080022import static org.junit.Assert.assertFalse;
23import static org.junit.Assert.assertTrue;
Kevin Han933dc7c2020-01-29 11:17:46 -080024import static org.mockito.ArgumentMatchers.any;
25import static org.mockito.ArgumentMatchers.eq;
Kevin4b8bbda2018-11-19 14:36:31 -080026import static org.mockito.Mockito.doReturn;
Selim Cinekc3fec682019-06-06 18:11:07 -070027import static org.mockito.Mockito.mock;
Kevin4b8bbda2018-11-19 14:36:31 -080028import static org.mockito.Mockito.spy;
Kevin01a53cb2018-11-09 18:19:54 -080029import static org.mockito.Mockito.verify;
30import static org.mockito.Mockito.when;
31
32import android.app.Notification;
Kevin4b8bbda2018-11-19 14:36:31 -080033import android.service.notification.StatusBarNotification;
Kevin01a53cb2018-11-09 18:19:54 -080034import android.testing.AndroidTestingRunner;
35import android.testing.TestableLooper;
36
Brett Chabot84151d92019-02-27 15:37:59 -080037import androidx.test.filters.SmallTest;
38
Kevin01a53cb2018-11-09 18:19:54 -080039import com.android.systemui.SysuiTestCase;
Lucas Dupind236ee32019-10-08 15:33:59 -070040import com.android.systemui.bubbles.BubbleController;
Selim Cinekc3fec682019-06-06 18:11:07 -070041import com.android.systemui.plugins.statusbar.StatusBarStateController;
Gus Prevasd65c2db2018-12-18 17:13:38 -050042import com.android.systemui.statusbar.notification.NotificationEntryListener;
Ned Burns3d6b3962018-12-07 21:26:00 -050043import com.android.systemui.statusbar.notification.NotificationEntryManager;
Ned Burnsf81c4c42019-01-07 14:10:43 -050044import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Kevin Han933dc7c2020-01-29 11:17:46 -080045import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback;
46import com.android.systemui.statusbar.notification.row.RowContentBindParams;
47import com.android.systemui.statusbar.notification.row.RowContentBindStage;
Kevin01a53cb2018-11-09 18:19:54 -080048import com.android.systemui.statusbar.policy.HeadsUpManager;
49
50import org.junit.Before;
51import org.junit.Rule;
52import org.junit.Test;
53import org.junit.runner.RunWith;
Ned Burns3d6b3962018-12-07 21:26:00 -050054import org.mockito.ArgumentCaptor;
55import org.mockito.Captor;
56import org.mockito.Mock;
Kevin Han933dc7c2020-01-29 11:17:46 -080057import org.mockito.MockitoAnnotations;
Kevin01a53cb2018-11-09 18:19:54 -080058import org.mockito.junit.MockitoJUnit;
59import org.mockito.junit.MockitoRule;
60
61import java.util.HashMap;
62
63@SmallTest
64@RunWith(AndroidTestingRunner.class)
65@TestableLooper.RunWithLooper
66public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase {
Ned Burns3d6b3962018-12-07 21:26:00 -050067 @Rule public MockitoRule rule = MockitoJUnit.rule();
Kevin01a53cb2018-11-09 18:19:54 -080068
69 private NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
70 private NotificationGroupManager mGroupManager;
Kevin01a53cb2018-11-09 18:19:54 -080071 private HeadsUpManager mHeadsUpManager;
Ned Burns3d6b3962018-12-07 21:26:00 -050072 @Mock private NotificationEntryManager mNotificationEntryManager;
Kevin Han933dc7c2020-01-29 11:17:46 -080073 @Mock private RowContentBindStage mBindStage;
74 @Captor private ArgumentCaptor<NotificationEntryListener> mListenerCaptor;
Gus Prevasd65c2db2018-12-18 17:13:38 -050075 private NotificationEntryListener mNotificationEntryListener;
Ned Burnsf81c4c42019-01-07 14:10:43 -050076 private final HashMap<String, NotificationEntry> mPendingEntries = new HashMap<>();
Kevin01a53cb2018-11-09 18:19:54 -080077 private final NotificationGroupTestHelper mGroupTestHelper =
78 new NotificationGroupTestHelper(mContext);
79
80
81 @Before
82 public void setup() {
Kevin Han933dc7c2020-01-29 11:17:46 -080083 MockitoAnnotations.initMocks(this);
Lucas Dupind236ee32019-10-08 15:33:59 -070084 mDependency.injectMockDependency(BubbleController.class);
Kevin01a53cb2018-11-09 18:19:54 -080085 mHeadsUpManager = new HeadsUpManager(mContext) {};
86
Ned Burns3d6b3962018-12-07 21:26:00 -050087 when(mNotificationEntryManager.getPendingNotificationsIterator())
88 .thenReturn(mPendingEntries.values());
89
Selim Cinekc3fec682019-06-06 18:11:07 -070090 mGroupManager = new NotificationGroupManager(mock(StatusBarStateController.class));
Kevin01a53cb2018-11-09 18:19:54 -080091 mDependency.injectTestDependency(NotificationGroupManager.class, mGroupManager);
92 mGroupManager.setHeadsUpManager(mHeadsUpManager);
93
Kevin Han933dc7c2020-01-29 11:17:46 -080094 when(mBindStage.getStageParams(any())).thenReturn(new RowContentBindParams());
95
96 mGroupAlertTransferHelper = new NotificationGroupAlertTransferHelper(mBindStage);
Kevin01a53cb2018-11-09 18:19:54 -080097 mGroupAlertTransferHelper.setHeadsUpManager(mHeadsUpManager);
Kevin01a53cb2018-11-09 18:19:54 -080098
Ned Burns3d6b3962018-12-07 21:26:00 -050099 mGroupAlertTransferHelper.bind(mNotificationEntryManager, mGroupManager);
Gus Prevasd65c2db2018-12-18 17:13:38 -0500100 verify(mNotificationEntryManager).addNotificationEntryListener(mListenerCaptor.capture());
101 mNotificationEntryListener = mListenerCaptor.getValue();
Kevin01a53cb2018-11-09 18:19:54 -0800102 mHeadsUpManager.addListener(mGroupAlertTransferHelper);
Kevin01a53cb2018-11-09 18:19:54 -0800103 }
104
105 @Test
106 public void testSuppressedSummaryHeadsUpTransfersToChild() {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500107 NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
Kevin01a53cb2018-11-09 18:19:54 -0800108 mHeadsUpManager.showNotification(summaryEntry);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500109 NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
Kevin01a53cb2018-11-09 18:19:54 -0800110
Kevin Han933dc7c2020-01-29 11:17:46 -0800111 RowContentBindParams params = new RowContentBindParams();
112 params.requireContentViews(FLAG_CONTENT_VIEW_HEADS_UP);
113 when(mBindStage.getStageParams(eq(childEntry))).thenReturn(params);
114
Kevin01a53cb2018-11-09 18:19:54 -0800115 // Summary will be suppressed because there is only one child.
116 mGroupManager.onEntryAdded(summaryEntry);
117 mGroupManager.onEntryAdded(childEntry);
118
119 // A suppressed summary should transfer its alert state to the child.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400120 assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
121 assertTrue(mHeadsUpManager.isAlerting(childEntry.getKey()));
Kevin01a53cb2018-11-09 18:19:54 -0800122 }
123
124 @Test
125 public void testSuppressedSummaryHeadsUpTransfersToChildButBackAgain() {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500126 NotificationEntry summaryEntry =
Kevin01a53cb2018-11-09 18:19:54 -0800127 mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500128 NotificationEntry childEntry =
Kevin01a53cb2018-11-09 18:19:54 -0800129 mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500130 NotificationEntry childEntry2 =
Kevin01a53cb2018-11-09 18:19:54 -0800131 mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
132 mHeadsUpManager.showNotification(summaryEntry);
133 // Trigger a transfer of alert state from summary to child.
134 mGroupManager.onEntryAdded(summaryEntry);
135 mGroupManager.onEntryAdded(childEntry);
136
137 // Add second child notification so that summary is no longer suppressed.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400138 mPendingEntries.put(childEntry2.getKey(), childEntry2);
Gus Prevasd65c2db2018-12-18 17:13:38 -0500139 mNotificationEntryListener.onPendingEntryAdded(childEntry2);
Kevin01a53cb2018-11-09 18:19:54 -0800140 mGroupManager.onEntryAdded(childEntry2);
141
142 // The alert state should transfer back to the summary as there is now more than one
143 // child and the summary should no longer be suppressed.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400144 assertTrue(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
145 assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
Kevin01a53cb2018-11-09 18:19:54 -0800146 }
147
148 @Test
149 public void testSuppressedSummaryHeadsUpDoesntTransferBackOnDozingChanged() {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500150 NotificationEntry summaryEntry =
Kevin01a53cb2018-11-09 18:19:54 -0800151 mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500152 NotificationEntry childEntry =
Kevin01a53cb2018-11-09 18:19:54 -0800153 mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500154 NotificationEntry childEntry2 =
Kevin01a53cb2018-11-09 18:19:54 -0800155 mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
156 mHeadsUpManager.showNotification(summaryEntry);
157 // Trigger a transfer of alert state from summary to child.
158 mGroupManager.onEntryAdded(summaryEntry);
159 mGroupManager.onEntryAdded(childEntry);
160
161 // Set dozing to true.
162 mGroupAlertTransferHelper.onDozingChanged(true);
163
164 // Add second child notification so that summary is no longer suppressed.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400165 mPendingEntries.put(childEntry2.getKey(), childEntry2);
Gus Prevasd65c2db2018-12-18 17:13:38 -0500166 mNotificationEntryListener.onPendingEntryAdded(childEntry2);
Kevin01a53cb2018-11-09 18:19:54 -0800167 mGroupManager.onEntryAdded(childEntry2);
168
169 // Dozing changed so no reason to re-alert summary.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400170 assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
Kevin01a53cb2018-11-09 18:19:54 -0800171 }
172
173 @Test
174 public void testSuppressedSummaryHeadsUpTransferDoesNotAlertChildIfUninflated() {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500175 NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
Kevin01a53cb2018-11-09 18:19:54 -0800176 mHeadsUpManager.showNotification(summaryEntry);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500177 NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
Kevin Han933dc7c2020-01-29 11:17:46 -0800178 RowContentBindParams params = new RowContentBindParams();
179 when(mBindStage.getStageParams(eq(childEntry))).thenReturn(params);
Kevin01a53cb2018-11-09 18:19:54 -0800180
181 mGroupManager.onEntryAdded(summaryEntry);
182 mGroupManager.onEntryAdded(childEntry);
183
184 // Alert is immediately removed from summary, but we do not show child yet either as its
185 // content is not inflated.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400186 assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
187 assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
Kevin4b8bbda2018-11-19 14:36:31 -0800188 assertTrue(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
Kevin01a53cb2018-11-09 18:19:54 -0800189 }
190
191 @Test
192 public void testSuppressedSummaryHeadsUpTransferAlertsChildOnInflation() {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500193 NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
Kevin01a53cb2018-11-09 18:19:54 -0800194 mHeadsUpManager.showNotification(summaryEntry);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500195 NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
Kevin Han933dc7c2020-01-29 11:17:46 -0800196 RowContentBindParams params = new RowContentBindParams();
197 when(mBindStage.getStageParams(eq(childEntry))).thenReturn(params);
Kevin01a53cb2018-11-09 18:19:54 -0800198
199 mGroupManager.onEntryAdded(summaryEntry);
200 mGroupManager.onEntryAdded(childEntry);
201
Kevin Han933dc7c2020-01-29 11:17:46 -0800202 // Child entry finishes its inflation.
203 ArgumentCaptor<BindCallback> callbackCaptor = ArgumentCaptor.forClass(BindCallback.class);
204 verify(mBindStage).requestRebind(eq(childEntry), callbackCaptor.capture());
205 callbackCaptor.getValue().onBindFinished(childEntry);
Kevin01a53cb2018-11-09 18:19:54 -0800206
207 // Alert is immediately removed from summary, and we show child as its content is inflated.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400208 assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
209 assertTrue(mHeadsUpManager.isAlerting(childEntry.getKey()));
Kevin01a53cb2018-11-09 18:19:54 -0800210 }
211
212 @Test
213 public void testSuppressedSummaryHeadsUpTransferBackAbortsChildInflation() {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500214 NotificationEntry summaryEntry =
Kevin01a53cb2018-11-09 18:19:54 -0800215 mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500216 NotificationEntry childEntry =
Kevin01a53cb2018-11-09 18:19:54 -0800217 mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
Kevin Han933dc7c2020-01-29 11:17:46 -0800218 RowContentBindParams params = new RowContentBindParams();
219 when(mBindStage.getStageParams(eq(childEntry))).thenReturn(params);
220
Ned Burnsf81c4c42019-01-07 14:10:43 -0500221 NotificationEntry childEntry2 =
Kevin01a53cb2018-11-09 18:19:54 -0800222 mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
223 mHeadsUpManager.showNotification(summaryEntry);
224 // Trigger a transfer of alert state from summary to child.
225 mGroupManager.onEntryAdded(summaryEntry);
226 mGroupManager.onEntryAdded(childEntry);
227
228 // Add second child notification so that summary is no longer suppressed.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400229 mPendingEntries.put(childEntry2.getKey(), childEntry2);
Gus Prevasd65c2db2018-12-18 17:13:38 -0500230 mNotificationEntryListener.onPendingEntryAdded(childEntry2);
Kevin01a53cb2018-11-09 18:19:54 -0800231 mGroupManager.onEntryAdded(childEntry2);
232
233 // Child entry finishes its inflation.
Kevin Han933dc7c2020-01-29 11:17:46 -0800234 ArgumentCaptor<BindCallback> callbackCaptor = ArgumentCaptor.forClass(BindCallback.class);
235 verify(mBindStage).requestRebind(eq(childEntry), callbackCaptor.capture());
236 callbackCaptor.getValue().onBindFinished(childEntry);
Kevin01a53cb2018-11-09 18:19:54 -0800237
Kevin Han273bb0d2020-03-20 10:44:40 -0700238 assertTrue((params.getContentViews() & FLAG_CONTENT_VIEW_HEADS_UP) == 0);
Ned Burns00b4b2d2019-10-17 22:09:27 -0400239 assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
Kevin01a53cb2018-11-09 18:19:54 -0800240 }
Kevin4b8bbda2018-11-19 14:36:31 -0800241
242 @Test
243 public void testCleanUpPendingAlertInfo() {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500244 NotificationEntry summaryEntry =
Kevin4b8bbda2018-11-19 14:36:31 -0800245 mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500246 NotificationEntry childEntry =
Kevin4b8bbda2018-11-19 14:36:31 -0800247 mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
Kevin Han933dc7c2020-01-29 11:17:46 -0800248 RowContentBindParams params = new RowContentBindParams();
249 when(mBindStage.getStageParams(eq(childEntry))).thenReturn(params);
250
Kevin4b8bbda2018-11-19 14:36:31 -0800251 mHeadsUpManager.showNotification(summaryEntry);
252 // Trigger a transfer of alert state from summary to child.
253 mGroupManager.onEntryAdded(summaryEntry);
254 mGroupManager.onEntryAdded(childEntry);
255
Julia Reynolds138111f2020-02-26 11:17:39 -0500256 mNotificationEntryListener.onEntryRemoved(
257 childEntry, null, false, UNDEFINED_DISMISS_REASON);
Kevin4b8bbda2018-11-19 14:36:31 -0800258
259 assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
260 }
261
262 @Test
263 public void testUpdateGroupChangeDoesNotTransfer() {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500264 NotificationEntry summaryEntry =
Kevin4b8bbda2018-11-19 14:36:31 -0800265 mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500266 NotificationEntry childEntry =
Kevin4b8bbda2018-11-19 14:36:31 -0800267 mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
Kevin Han933dc7c2020-01-29 11:17:46 -0800268 RowContentBindParams params = new RowContentBindParams();
269 when(mBindStage.getStageParams(eq(childEntry))).thenReturn(params);
270
Kevin4b8bbda2018-11-19 14:36:31 -0800271 mHeadsUpManager.showNotification(summaryEntry);
272 // Trigger a transfer of alert state from summary to child.
273 mGroupManager.onEntryAdded(summaryEntry);
274 mGroupManager.onEntryAdded(childEntry);
275
276 // Notify that entry changed groups.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400277 StatusBarNotification oldNotification = childEntry.getSbn();
278 StatusBarNotification newSbn = spy(childEntry.getSbn().clone());
Kevin4b8bbda2018-11-19 14:36:31 -0800279 doReturn("other_group").when(newSbn).getGroupKey();
Ned Burns00b4b2d2019-10-17 22:09:27 -0400280 childEntry.setSbn(newSbn);
Kevin4b8bbda2018-11-19 14:36:31 -0800281 mGroupManager.onEntryUpdated(childEntry, oldNotification);
282
283 assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
284 }
285
286 @Test
287 public void testUpdateChildToSummaryDoesNotTransfer() {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500288 NotificationEntry summaryEntry =
Kevin4b8bbda2018-11-19 14:36:31 -0800289 mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
Ned Burnsf81c4c42019-01-07 14:10:43 -0500290 NotificationEntry childEntry =
Ned Burnsae90a9e2019-08-26 17:11:26 -0400291 mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY, 47);
Kevin Han933dc7c2020-01-29 11:17:46 -0800292 RowContentBindParams params = new RowContentBindParams();
293 when(mBindStage.getStageParams(eq(childEntry))).thenReturn(params);
294
Kevin4b8bbda2018-11-19 14:36:31 -0800295 mHeadsUpManager.showNotification(summaryEntry);
296 // Trigger a transfer of alert state from summary to child.
297 mGroupManager.onEntryAdded(summaryEntry);
298 mGroupManager.onEntryAdded(childEntry);
299
300 // Update that child to a summary.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400301 StatusBarNotification oldNotification = childEntry.getSbn();
302 childEntry.setSbn(
Ned Burnsae90a9e2019-08-26 17:11:26 -0400303 mGroupTestHelper.createSummaryNotification(
Ned Burns00b4b2d2019-10-17 22:09:27 -0400304 Notification.GROUP_ALERT_SUMMARY, 47).getSbn());
Kevin4b8bbda2018-11-19 14:36:31 -0800305 mGroupManager.onEntryUpdated(childEntry, oldNotification);
306
307 assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
308 }
Kevin01a53cb2018-11-09 18:19:54 -0800309}