blob: 36398a6fc12202a142da8f351dd07dd598ce23bb [file] [log] [blame]
Mady Mellorebdbbb92018-11-15 14:36:48 -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.bubbles;
18
Mady Melloraa8fef22019-04-11 13:36:40 -070019import static android.app.Notification.FLAG_BUBBLE;
Mady Mellorc2ff0112019-03-28 14:18:06 -070020import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
21import static android.service.notification.NotificationListenerService.REASON_CANCEL;
22import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
Beverlya53fb0d2020-01-29 15:26:13 -050023import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
Mady Mellor1a4e86f2019-05-03 16:07:23 -070024
Mady Mellorfc02cc32019-04-01 14:47:55 -070025import static com.google.common.truth.Truth.assertThat;
26
Mady Melloredd4ee12019-01-18 10:45:11 -080027import static org.junit.Assert.assertEquals;
Mady Mellorebdbbb92018-11-15 14:36:48 -080028import static org.junit.Assert.assertFalse;
Mady Mellored99c272019-06-13 15:58:30 -070029import static org.junit.Assert.assertNotNull;
30import static org.junit.Assert.assertNull;
Mady Mellorebdbbb92018-11-15 14:36:48 -080031import static org.junit.Assert.assertTrue;
Mady Mellorc2ff0112019-03-28 14:18:06 -070032import static org.mockito.ArgumentMatchers.any;
Mady Mellorc2ff0112019-03-28 14:18:06 -070033import static org.mockito.ArgumentMatchers.anyInt;
Beverly85d4c192019-09-30 11:40:39 -040034import static org.mockito.ArgumentMatchers.anyString;
Beverlya53fb0d2020-01-29 15:26:13 -050035import static org.mockito.ArgumentMatchers.eq;
Ned Burns01e38212019-01-03 16:32:52 -050036import static org.mockito.Mockito.atLeastOnce;
Mady Melloraa8fef22019-04-11 13:36:40 -070037import static org.mockito.Mockito.mock;
Mark Renouf08bc42a2019-03-07 13:01:59 -050038import static org.mockito.Mockito.never;
39import static org.mockito.Mockito.times;
Ned Burns01e38212019-01-03 16:32:52 -050040import static org.mockito.Mockito.verify;
41import static org.mockito.Mockito.when;
Mady Mellorebdbbb92018-11-15 14:36:48 -080042
43import android.app.IActivityManager;
Mady Mellor9adfe6a2020-03-30 17:23:26 -070044import android.app.INotificationManager;
Mady Mellore80930e2019-03-21 16:00:45 -070045import android.app.Notification;
Mark Renouf08bc42a2019-03-07 13:01:59 -050046import android.app.PendingIntent;
Beverly Taid1e175c2020-03-10 16:37:04 +000047import android.hardware.display.AmbientDisplayConfiguration;
Mady Mellor80c25b22019-06-17 14:40:37 -070048import android.hardware.face.FaceManager;
Beverly Taid1e175c2020-03-10 16:37:04 +000049import android.os.Handler;
50import android.os.PowerManager;
51import android.service.dreams.IDreamManager;
Mady Mellor76343012020-05-13 11:02:50 -070052import android.service.notification.NotificationListenerService;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -040053import android.service.notification.ZenModeConfig;
Mady Mellorebdbbb92018-11-15 14:36:48 -080054import android.testing.AndroidTestingRunner;
55import android.testing.TestableLooper;
56import android.view.WindowManager;
Mady Mellorebdbbb92018-11-15 14:36:48 -080057
Brett Chabot84151d92019-02-27 15:37:59 -080058import androidx.test.filters.SmallTest;
59
Dave Mankoff2aff6c32019-10-14 17:40:37 -040060import com.android.internal.colorextraction.ColorExtractor;
Mady Mellor458a6262020-06-07 21:09:19 -070061import com.android.internal.statusbar.IStatusBarService;
Mady Mellorebdbbb92018-11-15 14:36:48 -080062import com.android.systemui.SysuiTestCase;
Dave Mankoff2aff6c32019-10-14 17:40:37 -040063import com.android.systemui.colorextraction.SysuiColorExtractor;
Ned Burnsaaeb44b2020-02-12 23:48:26 -050064import com.android.systemui.dump.DumpManager;
Joshua Tsujibe60a582020-03-23 17:17:26 -040065import com.android.systemui.model.SysUiState;
Mady Mellorc55b4122019-06-07 18:14:02 -070066import com.android.systemui.plugins.statusbar.StatusBarStateController;
Joshua Tsujibe60a582020-03-23 17:17:26 -040067import com.android.systemui.shared.system.QuickStepContract;
Beverlya53fb0d2020-01-29 15:26:13 -050068import com.android.systemui.statusbar.FeatureFlags;
Mark Renoufc19b4732019-06-26 12:08:33 -040069import com.android.systemui.statusbar.NotificationLockscreenUserManager;
Mady Mellorc2ff0112019-03-28 14:18:06 -070070import com.android.systemui.statusbar.NotificationRemoveInterceptor;
Mady Mellor76343012020-05-13 11:02:50 -070071import com.android.systemui.statusbar.RankingBuilder;
Lucas Dupine25c4872019-07-29 13:51:35 -070072import com.android.systemui.statusbar.SysuiStatusBarStateController;
Ned Burns01e38212019-01-03 16:32:52 -050073import com.android.systemui.statusbar.notification.NotificationEntryListener;
74import com.android.systemui.statusbar.notification.NotificationEntryManager;
Mady Mellorc55b4122019-06-07 18:14:02 -070075import com.android.systemui.statusbar.notification.NotificationFilter;
Beverlya53fb0d2020-01-29 15:26:13 -050076import com.android.systemui.statusbar.notification.collection.NotifPipeline;
Mady Mellor8d25b202019-06-25 13:59:28 -070077import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Mady Mellorebdbbb92018-11-15 14:36:48 -080078import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
Kevin Han933dc7c2020-01-29 11:17:46 -080079import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
Mady Mellorebdbbb92018-11-15 14:36:48 -080080import com.android.systemui.statusbar.phone.DozeParameters;
Lucas Dupine25c4872019-07-29 13:51:35 -070081import com.android.systemui.statusbar.phone.KeyguardBypassController;
Ned Burns296aec162019-09-04 17:30:59 -040082import com.android.systemui.statusbar.phone.NotificationGroupManager;
wilsonshihe8321942019-10-18 18:39:46 +080083import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
Fabian Kozynskib00c70b2020-04-03 12:41:31 -040084import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
Mady Mellor7f234902019-10-20 12:06:29 -070085import com.android.systemui.statusbar.phone.ShadeController;
Lucas Dupinbd7366d2019-09-25 13:39:21 -070086import com.android.systemui.statusbar.policy.BatteryController;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -070087import com.android.systemui.statusbar.policy.ConfigurationController;
Mady Melloraa8fef22019-04-11 13:36:40 -070088import com.android.systemui.statusbar.policy.HeadsUpManager;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -040089import com.android.systemui.statusbar.policy.ZenModeController;
Joshua Tsuji7155bf12020-02-13 16:14:29 -050090import com.android.systemui.util.FloatingContentCoordinator;
Mady Mellorebdbbb92018-11-15 14:36:48 -080091
Lyn Han89274b42020-03-25 00:56:26 -070092import com.google.common.collect.ImmutableList;
93
Mady Mellorebdbbb92018-11-15 14:36:48 -080094import org.junit.Before;
Josh Tsuji72e12cb2020-06-12 16:49:33 -040095import org.junit.Ignore;
Mady Mellorebdbbb92018-11-15 14:36:48 -080096import org.junit.Test;
97import org.junit.runner.RunWith;
Ned Burns01e38212019-01-03 16:32:52 -050098import org.mockito.ArgumentCaptor;
99import org.mockito.Captor;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800100import org.mockito.Mock;
101import org.mockito.MockitoAnnotations;
102
Beverlya53fb0d2020-01-29 15:26:13 -0500103import java.util.List;
104
105/**
106 * Tests the NotificationEntryManager setup with BubbleController.
107 * The {@link NotifPipeline} setup with BubbleController is tested in
108 * {@link NewNotifPipelineBubbleControllerTest}.
109 */
Mady Mellorebdbbb92018-11-15 14:36:48 -0800110@SmallTest
111@RunWith(AndroidTestingRunner.class)
112@TestableLooper.RunWithLooper(setAsMainLooper = true)
113public class BubbleControllerTest extends SysuiTestCase {
Mady Mellorebdbbb92018-11-15 14:36:48 -0800114 @Mock
Ned Burns01e38212019-01-03 16:32:52 -0500115 private NotificationEntryManager mNotificationEntryManager;
116 @Mock
Mady Mellor22f2f072019-04-18 13:26:18 -0700117 private NotificationGroupManager mNotificationGroupManager;
118 @Mock
Mady Mellorebdbbb92018-11-15 14:36:48 -0800119 private WindowManager mWindowManager;
120 @Mock
121 private IActivityManager mActivityManager;
122 @Mock
123 private DozeParameters mDozeParameters;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -0700124 @Mock
125 private ConfigurationController mConfigurationController;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -0400126 @Mock
127 private ZenModeController mZenModeController;
128 @Mock
129 private ZenModeConfig mZenModeConfig;
Mady Mellor80c25b22019-06-17 14:40:37 -0700130 @Mock
131 private FaceManager mFaceManager;
Mark Renoufc19b4732019-06-26 12:08:33 -0400132 @Mock
133 private NotificationLockscreenUserManager mLockscreenUserManager;
Mady Mellorf474e0d2019-08-01 11:08:40 -0700134 @Mock
Lucas Dupine25c4872019-07-29 13:51:35 -0700135 private SysuiStatusBarStateController mStatusBarStateController;
136 @Mock
137 private KeyguardBypassController mKeyguardBypassController;
Joshua Tsuji7155bf12020-02-13 16:14:29 -0500138 @Mock
139 private FloatingContentCoordinator mFloatingContentCoordinator;
Pinyao Tingee191b12020-04-29 18:35:39 -0700140 @Mock
141 private BubbleDataRepository mDataRepository;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -0700142
Joshua Tsujibe60a582020-03-23 17:17:26 -0400143 private SysUiState mSysUiState;
144 private boolean mSysUiStateBubblesExpanded;
145
Ned Burns01e38212019-01-03 16:32:52 -0500146 @Captor
147 private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
Mady Mellorc2ff0112019-03-28 14:18:06 -0700148 @Captor
149 private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800150
151 private TestableBubbleController mBubbleController;
wilsonshihe8321942019-10-18 18:39:46 +0800152 private NotificationShadeWindowController mNotificationShadeWindowController;
Ned Burns01e38212019-01-03 16:32:52 -0500153 private NotificationEntryListener mEntryListener;
Mady Mellorc2ff0112019-03-28 14:18:06 -0700154 private NotificationRemoveInterceptor mRemoveInterceptor;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800155
156 private NotificationTestHelper mNotificationTestHelper;
157 private ExpandableNotificationRow mRow;
158 private ExpandableNotificationRow mRow2;
Lyn Han2f6e89d2020-04-15 10:01:01 -0700159 private ExpandableNotificationRow mRow3;
Mady Mellorfc02cc32019-04-01 14:47:55 -0700160 private ExpandableNotificationRow mNonBubbleNotifRow;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800161
Mady Mellorb4991e62019-01-10 15:14:51 -0800162 @Mock
Mady Melloracb12152019-01-29 15:24:48 -0800163 private BubbleController.BubbleExpandListener mBubbleExpandListener;
Mark Renouf6b2331c2019-03-21 13:40:08 -0400164 @Mock
Mark Renouf08bc42a2019-03-07 13:01:59 -0500165 private PendingIntent mDeleteIntent;
Dave Mankoff2aff6c32019-10-14 17:40:37 -0400166 @Mock
167 private SysuiColorExtractor mColorExtractor;
168 @Mock
169 ColorExtractor.GradientColors mGradientColors;
Heemin Seogafb3dbc2019-11-04 16:05:19 -0800170 @Mock
Heemin Seogba6337f2019-12-10 15:34:37 -0800171 private ShadeController mShadeController;
Aran Inkaa4dfa72019-11-18 16:49:07 -0500172 @Mock
Beverlya53fb0d2020-01-29 15:26:13 -0500173 private NotifPipeline mNotifPipeline;
174 @Mock
175 private FeatureFlags mFeatureFlagsOldPipeline;
176 @Mock
Ned Burnsaaeb44b2020-02-12 23:48:26 -0500177 private DumpManager mDumpManager;
Dave Mankoffc0d9a7d2020-02-27 17:15:52 -0500178 @Mock
Fabian Kozynskib00c70b2020-04-03 12:41:31 -0400179 private NotificationShadeWindowView mNotificationShadeWindowView;
Mady Mellor458a6262020-06-07 21:09:19 -0700180 @Mock
181 private IStatusBarService mStatusBarService;
Mark Renouf08bc42a2019-03-07 13:01:59 -0500182
Mady Mellorcfd06c12019-02-13 14:32:12 -0800183 private BubbleData mBubbleData;
184
Mady Mellorb8aaf972019-11-26 10:28:00 -0800185 private TestableLooper mTestableLooper;
186
Mady Mellorebdbbb92018-11-15 14:36:48 -0800187 @Before
188 public void setUp() throws Exception {
189 MockitoAnnotations.initMocks(this);
Mady Mellorb8aaf972019-11-26 10:28:00 -0800190
191 mTestableLooper = TestableLooper.get(this);
192
Mady Mellor80c25b22019-06-17 14:40:37 -0700193 mContext.addMockSystemService(FaceManager.class, mFaceManager);
Dave Mankoff2aff6c32019-10-14 17:40:37 -0400194 when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800195
wilsonshihe8321942019-10-18 18:39:46 +0800196 mNotificationShadeWindowController = new NotificationShadeWindowController(mContext,
197 mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
Lucas Dupind73410a2020-02-18 12:54:41 -0800198 mConfigurationController, mKeyguardBypassController, mColorExtractor,
Ned Burnsaaeb44b2020-02-12 23:48:26 -0500199 mDumpManager);
Fabian Kozynskib00c70b2020-04-03 12:41:31 -0400200 mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
wilsonshihe8321942019-10-18 18:39:46 +0800201 mNotificationShadeWindowController.attach();
Mady Mellorebdbbb92018-11-15 14:36:48 -0800202
203 // Need notifications for bubbles
Kevin Hana7c21be2020-04-01 17:58:35 -0700204 mNotificationTestHelper = new NotificationTestHelper(
205 mContext,
206 mDependency,
207 TestableLooper.get(this));
Mark Renouf08bc42a2019-03-07 13:01:59 -0500208 mRow = mNotificationTestHelper.createBubble(mDeleteIntent);
209 mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700210 mRow3 = mNotificationTestHelper.createBubble(mDeleteIntent);
Mady Mellorfc02cc32019-04-01 14:47:55 -0700211 mNonBubbleNotifRow = mNotificationTestHelper.createRow();
Mady Mellor3ed46202019-03-26 20:22:35 -0700212
Ned Burns01e38212019-01-03 16:32:52 -0500213 // Return non-null notification data from the NEM
Evan Laird181de622019-10-24 09:53:02 -0400214 when(mNotificationEntryManager
215 .getActiveNotificationUnfiltered(mRow.getEntry().getKey())).thenReturn(
216 mRow.getEntry());
Ned Burns01e38212019-01-03 16:32:52 -0500217
Joshua Tsujidd4d9f92019-05-13 13:57:38 -0400218 mZenModeConfig.suppressedVisualEffects = 0;
219 when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
220
Joshua Tsujibe60a582020-03-23 17:17:26 -0400221 mSysUiState = new SysUiState();
222 mSysUiState.addCallback(sysUiFlags ->
223 mSysUiStateBubblesExpanded =
224 (sysUiFlags & QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED) != 0);
225
Beverly Taid1e175c2020-03-10 16:37:04 +0000226 TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
227 new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
228 mock(PowerManager.class),
229 mock(IDreamManager.class),
230 mock(AmbientDisplayConfiguration.class),
Mady Mellorc55b4122019-06-07 18:14:02 -0700231 mock(NotificationFilter.class),
Lucas Dupinbd7366d2019-09-25 13:39:21 -0700232 mock(StatusBarStateController.class),
Beverly Taid1e175c2020-03-10 16:37:04 +0000233 mock(BatteryController.class),
234 mock(HeadsUpManager.class),
235 mock(Handler.class)
236 );
Mark Renouf71a3af62019-04-08 15:02:54 -0400237 mBubbleData = new BubbleData(mContext);
Beverlya53fb0d2020-01-29 15:26:13 -0500238 when(mFeatureFlagsOldPipeline.isNewNotifPipelineRenderingEnabled()).thenReturn(false);
Ned Burnsaaeb44b2020-02-12 23:48:26 -0500239 mBubbleController = new TestableBubbleController(
240 mContext,
wilsonshihe8321942019-10-18 18:39:46 +0800241 mNotificationShadeWindowController,
Mady Mellor7f234902019-10-20 12:06:29 -0700242 mStatusBarStateController,
243 mShadeController,
Mady Mellor22f2f072019-04-18 13:26:18 -0700244 mBubbleData,
245 mConfigurationController,
246 interruptionStateProvider,
247 mZenModeController,
248 mLockscreenUserManager,
Mady Mellor7f234902019-10-20 12:06:29 -0700249 mNotificationGroupManager,
Beverlya53fb0d2020-01-29 15:26:13 -0500250 mNotificationEntryManager,
251 mNotifPipeline,
252 mFeatureFlagsOldPipeline,
Ned Burnsaaeb44b2020-02-12 23:48:26 -0500253 mDumpManager,
Joshua Tsujibe60a582020-03-23 17:17:26 -0400254 mFloatingContentCoordinator,
Pinyao Tingee191b12020-04-29 18:35:39 -0700255 mDataRepository,
Mady Mellor9adfe6a2020-03-30 17:23:26 -0700256 mSysUiState,
Mady Mellor59a7b982020-05-11 15:19:59 -0700257 mock(INotificationManager.class),
Mady Mellor458a6262020-06-07 21:09:19 -0700258 mStatusBarService,
Mady Mellor59a7b982020-05-11 15:19:59 -0700259 mWindowManager);
Mady Melloracb12152019-01-29 15:24:48 -0800260 mBubbleController.setExpandListener(mBubbleExpandListener);
Ned Burns01e38212019-01-03 16:32:52 -0500261
262 // Get a reference to the BubbleController's entry listener
263 verify(mNotificationEntryManager, atLeastOnce())
264 .addNotificationEntryListener(mEntryListenerCaptor.capture());
265 mEntryListener = mEntryListenerCaptor.getValue();
Mady Mellorc2ff0112019-03-28 14:18:06 -0700266 // And the remove interceptor
267 verify(mNotificationEntryManager, atLeastOnce())
Evan Laird04373662020-01-24 17:37:39 -0500268 .addNotificationRemoveInterceptor(mRemoveInterceptorCaptor.capture());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700269 mRemoveInterceptor = mRemoveInterceptorCaptor.getValue();
Mady Mellorebdbbb92018-11-15 14:36:48 -0800270 }
271
272 @Test
Mady Mellorebdbbb92018-11-15 14:36:48 -0800273 public void testAddBubble() {
Mark Renouff97ed462019-04-05 13:46:24 -0400274 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800275 assertTrue(mBubbleController.hasBubbles());
Mady Melloracb12152019-01-29 15:24:48 -0800276
Joshua Tsujibe60a582020-03-23 17:17:26 -0400277 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800278 }
279
280 @Test
281 public void testHasBubbles() {
282 assertFalse(mBubbleController.hasBubbles());
Mark Renouff97ed462019-04-05 13:46:24 -0400283 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800284 assertTrue(mBubbleController.hasBubbles());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400285 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800286 }
287
288 @Test
289 public void testRemoveBubble() {
Mark Renouff97ed462019-04-05 13:46:24 -0400290 mBubbleController.updateBubble(mRow.getEntry());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700291 assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Mady Mellorebdbbb92018-11-15 14:36:48 -0800292 assertTrue(mBubbleController.hasBubbles());
Beverly85d4c192019-09-30 11:40:39 -0400293 verify(mNotificationEntryManager).updateNotifications(any());
Mady Melloracb12152019-01-29 15:24:48 -0800294
Ned Burns00b4b2d2019-10-17 22:09:27 -0400295 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000296 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700297 assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Beverly85d4c192019-09-30 11:40:39 -0400298 verify(mNotificationEntryManager, times(2)).updateNotifications(anyString());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400299
300 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800301 }
302
303 @Test
Mady Mellor458a6262020-06-07 21:09:19 -0700304 public void testPromoteBubble_autoExpand() throws Exception {
Lyn Han89274b42020-03-25 00:56:26 -0700305 mBubbleController.updateBubble(mRow2.getEntry());
306 mBubbleController.updateBubble(mRow.getEntry());
Pinyao Ting175a5b82020-06-15 23:41:14 +0000307 when(mNotificationEntryManager.getPendingOrActiveNotif(mRow.getEntry().getKey()))
308 .thenReturn(mRow.getEntry());
309 when(mNotificationEntryManager.getPendingOrActiveNotif(mRow2.getEntry().getKey()))
310 .thenReturn(mRow2.getEntry());
Lyn Han89274b42020-03-25 00:56:26 -0700311 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000312 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Lyn Han89274b42020-03-25 00:56:26 -0700313
314 Bubble b = mBubbleData.getOverflowBubbleWithKey(mRow.getEntry().getKey());
315 assertThat(mBubbleData.getOverflowBubbles()).isEqualTo(ImmutableList.of(b));
Lyn Han2f6e89d2020-04-15 10:01:01 -0700316 verify(mNotificationEntryManager, never()).performRemoveNotification(
317 eq(mRow.getEntry().getSbn()), anyInt());
Mady Mellor458a6262020-06-07 21:09:19 -0700318 assertThat(mRow.getEntry().isBubble()).isFalse();
Lyn Han89274b42020-03-25 00:56:26 -0700319
Lyn Han2f6e89d2020-04-15 10:01:01 -0700320 Bubble b2 = mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey());
Lyn Han89274b42020-03-25 00:56:26 -0700321 assertThat(mBubbleData.getSelectedBubble()).isEqualTo(b2);
322
323 mBubbleController.promoteBubbleFromOverflow(b);
Mady Mellor458a6262020-06-07 21:09:19 -0700324
325 assertThat(b.isBubble()).isTrue();
326 assertThat(b.shouldAutoExpand()).isTrue();
327 int flags = Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE
328 | Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
329 verify(mStatusBarService, times(1)).onNotificationBubbleChanged(
330 eq(b.getKey()), eq(true), eq(flags));
Lyn Han89274b42020-03-25 00:56:26 -0700331 }
332
333 @Test
Lyn Han2f6e89d2020-04-15 10:01:01 -0700334 public void testCancelOverflowBubble() {
335 mBubbleController.updateBubble(mRow2.getEntry());
336 mBubbleController.updateBubble(mRow.getEntry(), /* suppressFlyout */
337 false, /* showInShade */ true);
Pinyao Ting175a5b82020-06-15 23:41:14 +0000338 when(mNotificationEntryManager.getPendingOrActiveNotif(mRow.getEntry().getKey()))
339 .thenReturn(mRow.getEntry());
340 when(mNotificationEntryManager.getPendingOrActiveNotif(mRow2.getEntry().getKey()))
341 .thenReturn(mRow2.getEntry());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400342 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000343 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700344
Pinyao Ting3c930612020-05-19 00:26:03 +0000345 mBubbleController.removeBubble(
346 mRow.getEntry().getKey(), BubbleController.DISMISS_NOTIF_CANCEL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700347 verify(mNotificationEntryManager, times(1)).performRemoveNotification(
Beverlya53fb0d2020-01-29 15:26:13 -0500348 eq(mRow.getEntry().getSbn()), anyInt());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700349 assertThat(mBubbleData.getOverflowBubbles()).isEmpty();
350 assertFalse(mRow.getEntry().isBubble());
351 }
Joshua Tsujibe60a582020-03-23 17:17:26 -0400352
Lyn Han2f6e89d2020-04-15 10:01:01 -0700353 @Test
354 public void testUserChange_doesNotRemoveNotif() {
355 mBubbleController.updateBubble(mRow.getEntry());
356 assertTrue(mBubbleController.hasBubbles());
357
358 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000359 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_CHANGED);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700360 verify(mNotificationEntryManager, never()).performRemoveNotification(
361 eq(mRow.getEntry().getSbn()), anyInt());
362 assertFalse(mBubbleController.hasBubbles());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400363 assertFalse(mSysUiStateBubblesExpanded);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700364 assertTrue(mRow.getEntry().isBubble());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700365 }
366
367 @Test
Mady Mellorebdbbb92018-11-15 14:36:48 -0800368 public void testDismissStack() {
Mark Renouff97ed462019-04-05 13:46:24 -0400369 mBubbleController.updateBubble(mRow.getEntry());
Beverly85d4c192019-09-30 11:40:39 -0400370 verify(mNotificationEntryManager, times(1)).updateNotifications(any());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700371 assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Mark Renouff97ed462019-04-05 13:46:24 -0400372 mBubbleController.updateBubble(mRow2.getEntry());
Beverly85d4c192019-09-30 11:40:39 -0400373 verify(mNotificationEntryManager, times(2)).updateNotifications(any());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700374 assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey()));
Mady Mellorebdbbb92018-11-15 14:36:48 -0800375 assertTrue(mBubbleController.hasBubbles());
376
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400377 mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE);
Beverly85d4c192019-09-30 11:40:39 -0400378 verify(mNotificationEntryManager, times(3)).updateNotifications(any());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700379 assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
380 assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey()));
Joshua Tsujibe60a582020-03-23 17:17:26 -0400381
382 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800383 }
384
385 @Test
Mady Melloracb12152019-01-29 15:24:48 -0800386 public void testExpandCollapseStack() {
Mady Mellorebdbbb92018-11-15 14:36:48 -0800387 assertFalse(mBubbleController.isStackExpanded());
Mady Melloracb12152019-01-29 15:24:48 -0800388
389 // Mark it as a bubble and add it explicitly
Mady Mellor78133512020-01-31 08:45:52 -0800390 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400391 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800392
Mady Mellorce23c462019-06-17 17:30:07 -0700393 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800394 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400395 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500396 mRow.getEntry()));
Mady Melloracb12152019-01-29 15:24:48 -0800397
398 // Expand the stack
Mady Mellorebdbbb92018-11-15 14:36:48 -0800399 BubbleStackView stackView = mBubbleController.getStackView();
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400400 mBubbleData.setExpanded(true);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800401 assertTrue(mBubbleController.isStackExpanded());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400402 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800403
Joshua Tsujibe60a582020-03-23 17:17:26 -0400404 assertTrue(mSysUiStateBubblesExpanded);
405
Mady Mellorce23c462019-06-17 17:30:07 -0700406 // Make sure the notif is suppressed
Ned Burns00b4b2d2019-10-17 22:09:27 -0400407 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500408 mRow.getEntry()));
Mady Melloracb12152019-01-29 15:24:48 -0800409
410 // Collapse
Mark Renouf71a3af62019-04-08 15:02:54 -0400411 mBubbleController.collapseStack();
Ned Burns00b4b2d2019-10-17 22:09:27 -0400412 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800413 assertFalse(mBubbleController.isStackExpanded());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400414
415 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800416 }
417
418 @Test
Josh Tsuji72e12cb2020-06-12 16:49:33 -0400419 @Ignore("Currently broken.")
Mady Melloracb12152019-01-29 15:24:48 -0800420 public void testCollapseAfterChangingExpandedBubble() {
421 // Mark it as a bubble and add it explicitly
Mady Mellor78133512020-01-31 08:45:52 -0800422 mEntryListener.onPendingEntryAdded(mRow.getEntry());
423 mEntryListener.onPendingEntryAdded(mRow2.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400424 mBubbleController.updateBubble(mRow.getEntry());
425 mBubbleController.updateBubble(mRow2.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800426
Mady Mellorce23c462019-06-17 17:30:07 -0700427 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800428 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700429 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500430 mRow.getEntry()));
Ned Burns00b4b2d2019-10-17 22:09:27 -0400431 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500432 mRow2.getEntry()));
Mady Melloracb12152019-01-29 15:24:48 -0800433
434 // Expand
Mady Mellorebdbbb92018-11-15 14:36:48 -0800435 BubbleStackView stackView = mBubbleController.getStackView();
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400436 mBubbleData.setExpanded(true);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800437 assertTrue(mBubbleController.isStackExpanded());
Joshua Tsuji06785ab2020-06-08 11:18:40 -0400438 verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged(
439 true, mRow2.getEntry().getKey());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800440
Joshua Tsujibe60a582020-03-23 17:17:26 -0400441 assertTrue(mSysUiStateBubblesExpanded);
442
Mark Renoufba5ab512019-05-02 15:21:01 -0400443 // Last added is the one that is expanded
Pinyao Ting175a5b82020-06-15 23:41:14 +0000444 assertEquals(mRow2.getEntry().getKey(), mBubbleData.getSelectedBubble().getKey());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400445 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500446 mRow2.getEntry()));
Mark Renouf71a3af62019-04-08 15:02:54 -0400447
Mark Renoufba5ab512019-05-02 15:21:01 -0400448 // Switch which bubble is expanded
Pinyao Ting175a5b82020-06-15 23:41:14 +0000449 mBubbleData.setSelectedBubble(mBubbleData.getBubbleInStackWithKey(
450 mRow.getEntry().getKey()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800451 mBubbleData.setExpanded(true);
Pinyao Ting175a5b82020-06-15 23:41:14 +0000452 assertEquals(mRow.getEntry().getKey(), mBubbleData.getBubbleInStackWithKey(
453 stackView.getExpandedBubble().getKey()).getKey());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400454 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500455 mRow.getEntry()));
Mark Renoufba5ab512019-05-02 15:21:01 -0400456
Mady Melloracb12152019-01-29 15:24:48 -0800457 // collapse for previous bubble
Joshua Tsuji06785ab2020-06-08 11:18:40 -0400458 verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged(
459 false, mRow2.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800460 // expand for selected bubble
Joshua Tsuji06785ab2020-06-08 11:18:40 -0400461 verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged(
462 true, mRow.getEntry().getKey());
Mady Melloredd4ee12019-01-18 10:45:11 -0800463
Mady Melloracb12152019-01-29 15:24:48 -0800464 // Collapse
Mady Mellorebdbbb92018-11-15 14:36:48 -0800465 mBubbleController.collapseStack();
466 assertFalse(mBubbleController.isStackExpanded());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400467
468 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800469 }
470
Ned Burns01e38212019-01-03 16:32:52 -0500471 @Test
Mady Melloraea895f02019-07-10 14:37:48 -0700472 public void testExpansionRemovesShowInShadeAndDot() {
Mady Melloracb12152019-01-29 15:24:48 -0800473 // Mark it as a bubble and add it explicitly
Mady Mellor78133512020-01-31 08:45:52 -0800474 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400475 mBubbleController.updateBubble(mRow.getEntry());
Mady Melloracb12152019-01-29 15:24:48 -0800476
Mady Mellorce23c462019-06-17 17:30:07 -0700477 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800478 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400479 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500480 mRow.getEntry()));
Mady Mellorb8aaf972019-11-26 10:28:00 -0800481
482 mTestableLooper.processAllMessages();
Lyn Han2f6e89d2020-04-15 10:01:01 -0700483 assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Melloracb12152019-01-29 15:24:48 -0800484
485 // Expand
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400486 mBubbleData.setExpanded(true);
Mady Melloracb12152019-01-29 15:24:48 -0800487 assertTrue(mBubbleController.isStackExpanded());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400488 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800489
Joshua Tsujibe60a582020-03-23 17:17:26 -0400490 assertTrue(mSysUiStateBubblesExpanded);
491
Mady Mellorce23c462019-06-17 17:30:07 -0700492 // Notif is suppressed after expansion
Ned Burns00b4b2d2019-10-17 22:09:27 -0400493 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500494 mRow.getEntry()));
Mady Melloraea895f02019-07-10 14:37:48 -0700495 // Notif shouldn't show dot after expansion
Lyn Han2f6e89d2020-04-15 10:01:01 -0700496 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Melloraea895f02019-07-10 14:37:48 -0700497 }
498
499 @Test
500 public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() {
501 // Mark it as a bubble and add it explicitly
Mady Mellor78133512020-01-31 08:45:52 -0800502 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Melloraea895f02019-07-10 14:37:48 -0700503 mBubbleController.updateBubble(mRow.getEntry());
504
505 // We should have bubbles & their notifs should not be suppressed
506 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400507 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500508 mRow.getEntry()));
Mady Mellorb8aaf972019-11-26 10:28:00 -0800509
510 mTestableLooper.processAllMessages();
Lyn Han2f6e89d2020-04-15 10:01:01 -0700511 assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Melloraea895f02019-07-10 14:37:48 -0700512
513 // Expand
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400514 mBubbleData.setExpanded(true);
Mady Melloraea895f02019-07-10 14:37:48 -0700515 assertTrue(mBubbleController.isStackExpanded());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400516 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
Mady Melloraea895f02019-07-10 14:37:48 -0700517
Joshua Tsujibe60a582020-03-23 17:17:26 -0400518 assertTrue(mSysUiStateBubblesExpanded);
519
Mady Melloraea895f02019-07-10 14:37:48 -0700520 // Notif is suppressed after expansion
Ned Burns00b4b2d2019-10-17 22:09:27 -0400521 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500522 mRow.getEntry()));
Mady Melloraea895f02019-07-10 14:37:48 -0700523 // Notif shouldn't show dot after expansion
Lyn Han2f6e89d2020-04-15 10:01:01 -0700524 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Melloraea895f02019-07-10 14:37:48 -0700525
526 // Send update
527 mEntryListener.onPreEntryUpdated(mRow.getEntry());
528
529 // Nothing should have changed
530 // Notif is suppressed after expansion
Ned Burns00b4b2d2019-10-17 22:09:27 -0400531 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500532 mRow.getEntry()));
Mady Melloraea895f02019-07-10 14:37:48 -0700533 // Notif shouldn't show dot after expansion
Lyn Han2f6e89d2020-04-15 10:01:01 -0700534 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Melloracb12152019-01-29 15:24:48 -0800535 }
536
537 @Test
538 public void testRemoveLastExpandedCollapses() {
539 // Mark it as a bubble and add it explicitly
Mady Mellor78133512020-01-31 08:45:52 -0800540 mEntryListener.onPendingEntryAdded(mRow.getEntry());
541 mEntryListener.onPendingEntryAdded(mRow2.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400542 mBubbleController.updateBubble(mRow.getEntry());
543 mBubbleController.updateBubble(mRow2.getEntry());
Mady Melloracb12152019-01-29 15:24:48 -0800544
545 // Expand
546 BubbleStackView stackView = mBubbleController.getStackView();
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400547 mBubbleData.setExpanded(true);
Mady Melloracb12152019-01-29 15:24:48 -0800548
Joshua Tsujibe60a582020-03-23 17:17:26 -0400549 assertTrue(mSysUiStateBubblesExpanded);
550
Mady Melloracb12152019-01-29 15:24:48 -0800551 assertTrue(mBubbleController.isStackExpanded());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400552 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800553
Mark Renoufba5ab512019-05-02 15:21:01 -0400554 // Last added is the one that is expanded
Pinyao Ting175a5b82020-06-15 23:41:14 +0000555 assertEquals(mRow2.getEntry().getKey(), mBubbleData.getBubbleInStackWithKey(
556 stackView.getExpandedBubble().getKey()).getKey());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400557 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500558 mRow2.getEntry()));
Mady Melloracb12152019-01-29 15:24:48 -0800559
560 // Dismiss currently expanded
Lyn Han9f66c3b2020-03-05 23:59:29 -0800561 mBubbleController.removeBubble(
Pinyao Ting175a5b82020-06-15 23:41:14 +0000562 mBubbleData.getBubbleInStackWithKey(
563 stackView.getExpandedBubble().getKey()).getKey(),
Mark Renouf08bc42a2019-03-07 13:01:59 -0500564 BubbleController.DISMISS_USER_GESTURE);
Ned Burns00b4b2d2019-10-17 22:09:27 -0400565 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800566
Mark Renoufba5ab512019-05-02 15:21:01 -0400567 // Make sure first bubble is selected
Pinyao Ting175a5b82020-06-15 23:41:14 +0000568 assertEquals(mRow.getEntry().getKey(), mBubbleData.getBubbleInStackWithKey(
569 stackView.getExpandedBubble().getKey()).getKey());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400570 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800571
572 // Dismiss that one
Lyn Han9f66c3b2020-03-05 23:59:29 -0800573 mBubbleController.removeBubble(
Pinyao Ting175a5b82020-06-15 23:41:14 +0000574 mBubbleData.getBubbleInStackWithKey(
575 stackView.getExpandedBubble().getKey()).getKey(),
Mark Renouf08bc42a2019-03-07 13:01:59 -0500576 BubbleController.DISMISS_USER_GESTURE);
Mady Melloracb12152019-01-29 15:24:48 -0800577
578 // Make sure state changes and collapse happens
Ned Burns00b4b2d2019-10-17 22:09:27 -0400579 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800580 assertFalse(mBubbleController.hasBubbles());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400581
582 assertFalse(mSysUiStateBubblesExpanded);
Mady Melloracb12152019-01-29 15:24:48 -0800583 }
584
585 @Test
Mady Mellorb25f9062019-12-09 12:12:57 -0800586 public void testAutoExpand_fails_noFlag() {
Mady Mellore80930e2019-03-21 16:00:45 -0700587 assertFalse(mBubbleController.isStackExpanded());
Mady Mellor8d25b202019-06-25 13:59:28 -0700588 setMetadataFlags(mRow.getEntry(),
589 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, false /* enableFlag */);
Mady Mellore80930e2019-03-21 16:00:45 -0700590
591 // Add the auto expand bubble
Mady Mellor78133512020-01-31 08:45:52 -0800592 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellor8d25b202019-06-25 13:59:28 -0700593 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellore80930e2019-03-21 16:00:45 -0700594
595 // Expansion shouldn't change
596 verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */,
Ned Burns00b4b2d2019-10-17 22:09:27 -0400597 mRow.getEntry().getKey());
Mady Mellore80930e2019-03-21 16:00:45 -0700598 assertFalse(mBubbleController.isStackExpanded());
599
Joshua Tsujibe60a582020-03-23 17:17:26 -0400600 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellore80930e2019-03-21 16:00:45 -0700601 }
602
603 @Test
Mady Mellorb25f9062019-12-09 12:12:57 -0800604 public void testAutoExpand_succeeds_withFlag() {
Mady Mellor8d25b202019-06-25 13:59:28 -0700605 setMetadataFlags(mRow.getEntry(),
606 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */);
Mady Mellore80930e2019-03-21 16:00:45 -0700607
608 // Add the auto expand bubble
Mady Mellor78133512020-01-31 08:45:52 -0800609 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellor8d25b202019-06-25 13:59:28 -0700610 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellore80930e2019-03-21 16:00:45 -0700611
612 // Expansion should change
613 verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */,
Ned Burns00b4b2d2019-10-17 22:09:27 -0400614 mRow.getEntry().getKey());
Mady Mellore80930e2019-03-21 16:00:45 -0700615 assertTrue(mBubbleController.isStackExpanded());
616
Joshua Tsujibe60a582020-03-23 17:17:26 -0400617 assertTrue(mSysUiStateBubblesExpanded);
Mady Mellore80930e2019-03-21 16:00:45 -0700618 }
619
Mady Mellor3ed46202019-03-26 20:22:35 -0700620 @Test
Mady Mellorb25f9062019-12-09 12:12:57 -0800621 public void testSuppressNotif_onInitialNotif() {
Mady Mellor8d25b202019-06-25 13:59:28 -0700622 setMetadataFlags(mRow.getEntry(),
623 Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */);
Mady Mellor3ed46202019-03-26 20:22:35 -0700624
625 // Add the suppress notif bubble
Mady Mellor78133512020-01-31 08:45:52 -0800626 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellor8d25b202019-06-25 13:59:28 -0700627 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellor3ed46202019-03-26 20:22:35 -0700628
Mady Mellorce23c462019-06-17 17:30:07 -0700629 // Notif should be suppressed because we were foreground
Ned Burns00b4b2d2019-10-17 22:09:27 -0400630 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500631 mRow.getEntry()));
Mady Mellorb25f9062019-12-09 12:12:57 -0800632 // Dot + flyout is hidden because notif is suppressed
Lyn Han2f6e89d2020-04-15 10:01:01 -0700633 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
634 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout());
Mady Mellor3ed46202019-03-26 20:22:35 -0700635
Joshua Tsujibe60a582020-03-23 17:17:26 -0400636 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellor3ed46202019-03-26 20:22:35 -0700637 }
Mady Mellore80930e2019-03-21 16:00:45 -0700638
639 @Test
Mady Mellorb25f9062019-12-09 12:12:57 -0800640 public void testSuppressNotif_onUpdateNotif() {
641 mBubbleController.updateBubble(mRow.getEntry());
642
643 // Should not be suppressed
644 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500645 mRow.getEntry()));
Mady Mellorb25f9062019-12-09 12:12:57 -0800646 // Should show dot
Lyn Han2f6e89d2020-04-15 10:01:01 -0700647 assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Mellorb25f9062019-12-09 12:12:57 -0800648
649 // Update to suppress notif
650 setMetadataFlags(mRow.getEntry(),
651 Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */);
652 mBubbleController.updateBubble(mRow.getEntry());
653
654 // Notif should be suppressed
655 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500656 mRow.getEntry()));
Mady Mellorb25f9062019-12-09 12:12:57 -0800657 // Dot + flyout is hidden because notif is suppressed
Lyn Han2f6e89d2020-04-15 10:01:01 -0700658 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
659 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout());
Mady Mellorb25f9062019-12-09 12:12:57 -0800660
Joshua Tsujibe60a582020-03-23 17:17:26 -0400661 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorb25f9062019-12-09 12:12:57 -0800662 }
663
Mady Mellorb25f9062019-12-09 12:12:57 -0800664 @Test
Mark Renouffec45da2019-03-13 13:24:27 -0400665 public void testExpandStackAndSelectBubble_removedFirst() {
Ned Burns00b4b2d2019-10-17 22:09:27 -0400666 final String key = mRow.getEntry().getKey();
Mark Renouffec45da2019-03-13 13:24:27 -0400667
Mady Mellor78133512020-01-31 08:45:52 -0800668 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400669 mBubbleController.updateBubble(mRow.getEntry());
Mark Renouffec45da2019-03-13 13:24:27 -0400670
Mark Renouffec45da2019-03-13 13:24:27 -0400671 // Simulate notification cancellation.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400672 mRemoveInterceptor.onNotificationRemoveRequested(
Evan Laird04373662020-01-24 17:37:39 -0500673 mRow.getEntry().getKey(), mRow.getEntry(), REASON_APP_CANCEL);
Mark Renouffec45da2019-03-13 13:24:27 -0400674
Mady Mellor76343012020-05-13 11:02:50 -0700675 mBubbleController.expandStackAndSelectBubble(mRow.getEntry());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400676
677 assertTrue(mSysUiStateBubblesExpanded);
Mark Renouffec45da2019-03-13 13:24:27 -0400678 }
679
680 @Test
Mady Mellor3f2efdb2018-11-21 11:30:45 -0800681 public void testMarkNewNotificationAsShowInShade() {
Mady Mellor78133512020-01-31 08:45:52 -0800682 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400683 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500684 mRow.getEntry()));
Mady Mellorb8aaf972019-11-26 10:28:00 -0800685
686 mTestableLooper.processAllMessages();
Lyn Han2f6e89d2020-04-15 10:01:01 -0700687 assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Mellor3f2efdb2018-11-21 11:30:45 -0800688 }
689
Mark Renouf08bc42a2019-03-07 13:01:59 -0500690 @Test
Mady Mellorfc02cc32019-04-01 14:47:55 -0700691 public void testAddNotif_notBubble() {
Mady Mellor78133512020-01-31 08:45:52 -0800692 mEntryListener.onPendingEntryAdded(mNonBubbleNotifRow.getEntry());
Mady Mellorfc02cc32019-04-01 14:47:55 -0700693 mEntryListener.onPreEntryUpdated(mNonBubbleNotifRow.getEntry());
694
Mady Mellorfc02cc32019-04-01 14:47:55 -0700695 assertThat(mBubbleController.hasBubbles()).isFalse();
696 }
697
698 @Test
Mark Renouf08bc42a2019-03-07 13:01:59 -0500699 public void testDeleteIntent_removeBubble_aged() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400700 mBubbleController.updateBubble(mRow.getEntry());
Pinyao Ting3c930612020-05-19 00:26:03 +0000701 mBubbleController.removeBubble(mRow.getEntry().getKey(), BubbleController.DISMISS_AGED);
Mark Renouf08bc42a2019-03-07 13:01:59 -0500702 verify(mDeleteIntent, never()).send();
703 }
704
705 @Test
706 public void testDeleteIntent_removeBubble_user() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400707 mBubbleController.updateBubble(mRow.getEntry());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400708 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000709 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Mark Renouf08bc42a2019-03-07 13:01:59 -0500710 verify(mDeleteIntent, times(1)).send();
711 }
712
713 @Test
714 public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400715 mBubbleController.updateBubble(mRow.getEntry());
716 mBubbleController.updateBubble(mRow2.getEntry());
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400717 mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE);
Mark Renouf08bc42a2019-03-07 13:01:59 -0500718 verify(mDeleteIntent, times(2)).send();
719 }
720
Mady Melloraa8fef22019-04-11 13:36:40 -0700721 @Test
722 public void testRemoveBubble_noLongerBubbleAfterUpdate()
723 throws PendingIntent.CanceledException {
724 mBubbleController.updateBubble(mRow.getEntry());
725 assertTrue(mBubbleController.hasBubbles());
726
Ned Burns00b4b2d2019-10-17 22:09:27 -0400727 mRow.getEntry().getSbn().getNotification().flags &= ~FLAG_BUBBLE;
Mady Mellor76343012020-05-13 11:02:50 -0700728 NotificationListenerService.Ranking ranking = new RankingBuilder(
729 mRow.getEntry().getRanking()).setCanBubble(false).build();
730 mRow.getEntry().setRanking(ranking);
Mady Melloraa8fef22019-04-11 13:36:40 -0700731 mEntryListener.onPreEntryUpdated(mRow.getEntry());
732
733 assertFalse(mBubbleController.hasBubbles());
734 verify(mDeleteIntent, never()).send();
735 }
736
Mady Mellorc2ff0112019-03-28 14:18:06 -0700737 @Test
738 public void testRemoveBubble_succeeds_appCancel() {
Mady Mellor78133512020-01-31 08:45:52 -0800739 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700740 mBubbleController.updateBubble(mRow.getEntry());
741
742 assertTrue(mBubbleController.hasBubbles());
743
744 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
Evan Laird04373662020-01-24 17:37:39 -0500745 mRow.getEntry().getKey(), mRow.getEntry(), REASON_APP_CANCEL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700746
747 // Cancels always remove so no need to intercept
748 assertFalse(intercepted);
Beverlya53fb0d2020-01-29 15:26:13 -0500749 }
750
751 @Test
752 public void testRemoveBubble_entryListenerRemove() {
753 mEntryListener.onPendingEntryAdded(mRow.getEntry());
754 mBubbleController.updateBubble(mRow.getEntry());
755
756 assertTrue(mBubbleController.hasBubbles());
757
758 // Removes the notification
Julia Reynolds138111f2020-02-26 11:17:39 -0500759 mEntryListener.onEntryRemoved(mRow.getEntry(), null, false, REASON_APP_CANCEL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700760 assertFalse(mBubbleController.hasBubbles());
761 }
762
763 @Test
Beverlya53fb0d2020-01-29 15:26:13 -0500764 public void removeBubble_clearAllIntercepted() {
Mady Mellor78133512020-01-31 08:45:52 -0800765 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700766 mBubbleController.updateBubble(mRow.getEntry());
767
768 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400769 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500770 mRow.getEntry()));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700771
772 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
Evan Laird04373662020-01-24 17:37:39 -0500773 mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL_ALL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700774
775 // Intercept!
776 assertTrue(intercepted);
777 // Should update show in shade state
Ned Burns00b4b2d2019-10-17 22:09:27 -0400778 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500779 mRow.getEntry()));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700780 }
781
782 @Test
Beverlya53fb0d2020-01-29 15:26:13 -0500783 public void removeBubble_userDismissNotifIntercepted() {
Mady Mellor78133512020-01-31 08:45:52 -0800784 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700785 mBubbleController.updateBubble(mRow.getEntry());
786
787 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400788 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500789 mRow.getEntry()));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700790
791 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
Evan Laird04373662020-01-24 17:37:39 -0500792 mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700793
794 // Intercept!
795 assertTrue(intercepted);
796 // Should update show in shade state
Ned Burns00b4b2d2019-10-17 22:09:27 -0400797 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500798 mRow.getEntry()));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700799 }
800
801 @Test
Lyn Han2f6e89d2020-04-15 10:01:01 -0700802 public void removeNotif_inOverflow_intercepted() {
803 // Get bubble with notif in shade.
804 mEntryListener.onPendingEntryAdded(mRow.getEntry());
805 mBubbleController.updateBubble(mRow.getEntry());
806 assertTrue(mBubbleController.hasBubbles());
807 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
808 mRow.getEntry()));
809
810 // Dismiss the bubble into overflow.
811 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000812 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700813 assertFalse(mBubbleController.hasBubbles());
814
815 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
816 mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL);
817
818 // Notif is no longer a bubble, but still in overflow, so we intercept removal.
819 assertTrue(intercepted);
820 }
821
822 @Test
823 public void removeNotif_notInOverflow_notIntercepted() {
824 // Get bubble with notif in shade.
Mady Mellor78133512020-01-31 08:45:52 -0800825 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700826 mBubbleController.updateBubble(mRow.getEntry());
827
828 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400829 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500830 mRow.getEntry()));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700831
Ned Burns00b4b2d2019-10-17 22:09:27 -0400832 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000833 mRow.getEntry().getKey(), BubbleController.DISMISS_NO_LONGER_BUBBLE);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700834 assertFalse(mBubbleController.hasBubbles());
835
Mady Mellorc2ff0112019-03-28 14:18:06 -0700836 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
Evan Laird04373662020-01-24 17:37:39 -0500837 mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700838
Lyn Han2f6e89d2020-04-15 10:01:01 -0700839 // Notif is no longer a bubble, so we should not intercept removal.
Mady Mellorc2ff0112019-03-28 14:18:06 -0700840 assertFalse(intercepted);
841 }
842
Mady Mellorf44b6832020-01-14 13:26:14 -0800843 @Test
Lyn Han2f6e89d2020-04-15 10:01:01 -0700844 public void testOverflowBubble_maxReached_notInShade_bubbleRemoved() {
845 mBubbleController.updateBubble(
846 mRow.getEntry(), /* suppressFlyout */ false, /* showInShade */ false);
847 mBubbleController.updateBubble(
848 mRow2.getEntry(), /* suppressFlyout */ false, /* showInShade */ false);
849 mBubbleController.updateBubble(
850 mRow3.getEntry(), /* suppressFlyout */ false, /* showInShade */ false);
Pinyao Ting175a5b82020-06-15 23:41:14 +0000851 when(mNotificationEntryManager.getPendingOrActiveNotif(mRow.getEntry().getKey()))
852 .thenReturn(mRow.getEntry());
853 when(mNotificationEntryManager.getPendingOrActiveNotif(mRow2.getEntry().getKey()))
854 .thenReturn(mRow2.getEntry());
855 when(mNotificationEntryManager.getPendingOrActiveNotif(mRow3.getEntry().getKey()))
856 .thenReturn(mRow3.getEntry());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700857 assertEquals(mBubbleData.getBubbles().size(), 3);
858
859 mBubbleData.setMaxOverflowBubbles(1);
860 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000861 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700862 assertEquals(mBubbleData.getBubbles().size(), 2);
863 assertEquals(mBubbleData.getOverflowBubbles().size(), 1);
864
865 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000866 mRow2.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700867 // Overflow max of 1 is reached; mRow is oldest, so it gets removed
868 verify(mNotificationEntryManager, times(1)).performRemoveNotification(
869 mRow.getEntry().getSbn(), REASON_CANCEL);
870 assertEquals(mBubbleData.getBubbles().size(), 1);
871 assertEquals(mBubbleData.getOverflowBubbles().size(), 1);
872 }
873
874 @Test
Mady Mellorf44b6832020-01-14 13:26:14 -0800875 public void testNotifyShadeSuppressionChange_notificationDismiss() {
876 BubbleController.NotificationSuppressionChangedListener listener =
877 mock(BubbleController.NotificationSuppressionChangedListener.class);
878 mBubbleData.setSuppressionChangedListener(listener);
879
Mady Mellor78133512020-01-31 08:45:52 -0800880 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorf44b6832020-01-14 13:26:14 -0800881
882 assertTrue(mBubbleController.hasBubbles());
883 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500884 mRow.getEntry()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800885
Evan Laird04373662020-01-24 17:37:39 -0500886 mRemoveInterceptor.onNotificationRemoveRequested(
887 mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL);
Mady Mellorf44b6832020-01-14 13:26:14 -0800888
889 // Should update show in shade state
890 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500891 mRow.getEntry()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800892
893 // Should notify delegate that shade state changed
894 verify(listener).onBubbleNotificationSuppressionChange(
Lyn Han2f6e89d2020-04-15 10:01:01 -0700895 mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800896 }
897
898 @Test
899 public void testNotifyShadeSuppressionChange_bubbleExpanded() {
900 BubbleController.NotificationSuppressionChangedListener listener =
901 mock(BubbleController.NotificationSuppressionChangedListener.class);
902 mBubbleData.setSuppressionChangedListener(listener);
903
Mady Mellor78133512020-01-31 08:45:52 -0800904 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorf44b6832020-01-14 13:26:14 -0800905
906 assertTrue(mBubbleController.hasBubbles());
907 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500908 mRow.getEntry()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800909
910 mBubbleData.setExpanded(true);
911
912 // Once a bubble is expanded the notif is suppressed
913 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500914 mRow.getEntry()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800915
916 // Should notify delegate that shade state changed
917 verify(listener).onBubbleNotificationSuppressionChange(
Lyn Han2f6e89d2020-04-15 10:01:01 -0700918 mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800919 }
920
Beverlya53fb0d2020-01-29 15:26:13 -0500921 @Test
922 public void testBubbleSummaryDismissal_suppressesSummaryAndBubbleFromShade() throws Exception {
923 // GIVEN a group summary with a bubble child
924 ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0);
925 ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
Pinyao Ting175a5b82020-06-15 23:41:14 +0000926 when(mNotificationEntryManager.getPendingOrActiveNotif(groupedBubble.getEntry().getKey()))
927 .thenReturn(groupedBubble.getEntry());
Beverlya53fb0d2020-01-29 15:26:13 -0500928 mEntryListener.onPendingEntryAdded(groupedBubble.getEntry());
929 groupSummary.addChildNotification(groupedBubble);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700930 assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
Beverlya53fb0d2020-01-29 15:26:13 -0500931
932 // WHEN the summary is dismissed
933 mBubbleController.handleDismissalInterception(groupSummary.getEntry());
934
935 // THEN the summary and bubbled child are suppressed from the shade
936 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
937 groupedBubble.getEntry()));
938 assertTrue(mBubbleData.isSummarySuppressed(groupSummary.getEntry().getSbn().getGroupKey()));
939 }
940
941 @Test
942 public void testAppRemovesSummary_removesAllBubbleChildren() throws Exception {
943 // GIVEN a group summary with a bubble child
944 ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0);
945 ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
946 mEntryListener.onPendingEntryAdded(groupedBubble.getEntry());
Pinyao Ting175a5b82020-06-15 23:41:14 +0000947 when(mNotificationEntryManager.getPendingOrActiveNotif(groupedBubble.getEntry().getKey()))
948 .thenReturn(groupedBubble.getEntry());
Beverlya53fb0d2020-01-29 15:26:13 -0500949 groupSummary.addChildNotification(groupedBubble);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700950 assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
Beverlya53fb0d2020-01-29 15:26:13 -0500951
952 // GIVEN the summary is dismissed
953 mBubbleController.handleDismissalInterception(groupSummary.getEntry());
954
955 // WHEN the summary is cancelled by the app
Julia Reynolds138111f2020-02-26 11:17:39 -0500956 mEntryListener.onEntryRemoved(groupSummary.getEntry(), null, false, REASON_APP_CANCEL);
Beverlya53fb0d2020-01-29 15:26:13 -0500957
958 // THEN the summary and its children are removed from bubble data
Lyn Han2f6e89d2020-04-15 10:01:01 -0700959 assertFalse(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
Beverlya53fb0d2020-01-29 15:26:13 -0500960 assertFalse(mBubbleData.isSummarySuppressed(
961 groupSummary.getEntry().getSbn().getGroupKey()));
962 }
963
964 @Test
965 public void testSummaryDismissal_marksBubblesHiddenFromShadeAndDismissesNonBubbledChildren()
966 throws Exception {
967 // GIVEN a group summary with two (non-bubble) children and one bubble child
968 ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(2);
969 ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
Pinyao Ting175a5b82020-06-15 23:41:14 +0000970 when(mNotificationEntryManager.getPendingOrActiveNotif(groupedBubble.getEntry().getKey()))
971 .thenReturn(groupedBubble.getEntry());
Beverlya53fb0d2020-01-29 15:26:13 -0500972 mEntryListener.onPendingEntryAdded(groupedBubble.getEntry());
973 groupSummary.addChildNotification(groupedBubble);
974
975 // WHEN the summary is dismissed
976 mBubbleController.handleDismissalInterception(groupSummary.getEntry());
977
978 // THEN only the NON-bubble children are dismissed
Kevin Han43077f92020-02-28 12:51:53 -0800979 List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren();
Beverlya53fb0d2020-01-29 15:26:13 -0500980 verify(mNotificationEntryManager, times(1)).performRemoveNotification(
981 childrenRows.get(0).getEntry().getSbn(), REASON_GROUP_SUMMARY_CANCELED);
982 verify(mNotificationEntryManager, times(1)).performRemoveNotification(
983 childrenRows.get(1).getEntry().getSbn(), REASON_GROUP_SUMMARY_CANCELED);
984 verify(mNotificationEntryManager, never()).performRemoveNotification(
985 eq(groupedBubble.getEntry().getSbn()), anyInt());
986
987 // THEN the bubble child is suppressed from the shade
988 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
989 groupedBubble.getEntry()));
990
991 // THEN the summary is removed from GroupManager
992 verify(mNotificationGroupManager, times(1)).onEntryRemoved(groupSummary.getEntry());
993 }
994
Mady Mellore80930e2019-03-21 16:00:45 -0700995 /**
Aran Inkc4381c42020-02-06 13:11:53 -0500996 * Sets the bubble metadata flags for this entry. These ]flags are normally set by
Mady Mellor8d25b202019-06-25 13:59:28 -0700997 * NotificationManagerService when the notification is sent, however, these tests do not
998 * go through that path so we set them explicitly when testing.
999 */
1000 private void setMetadataFlags(NotificationEntry entry, int flag, boolean enableFlag) {
1001 Notification.BubbleMetadata bubbleMetadata =
Ned Burns00b4b2d2019-10-17 22:09:27 -04001002 entry.getSbn().getNotification().getBubbleMetadata();
Mady Mellor8d25b202019-06-25 13:59:28 -07001003 int flags = bubbleMetadata.getFlags();
1004 if (enableFlag) {
1005 flags |= flag;
1006 } else {
1007 flags &= ~flag;
1008 }
1009 bubbleMetadata.setFlags(flags);
1010 }
Mady Mellorebdbbb92018-11-15 14:36:48 -08001011}