blob: c89f6c2597d0f5df67fcf72e16495d7fa904e3dc [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;
Heemin Seogafb3dbc2019-11-04 16:05:19 -080047import android.content.res.Resources;
Beverly Taid1e175c2020-03-10 16:37:04 +000048import android.hardware.display.AmbientDisplayConfiguration;
Mady Mellor80c25b22019-06-17 14:40:37 -070049import android.hardware.face.FaceManager;
Beverly Taid1e175c2020-03-10 16:37:04 +000050import android.os.Handler;
51import android.os.PowerManager;
52import android.service.dreams.IDreamManager;
Mady Mellor76343012020-05-13 11:02:50 -070053import android.service.notification.NotificationListenerService;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -040054import android.service.notification.ZenModeConfig;
Mady Mellorebdbbb92018-11-15 14:36:48 -080055import android.testing.AndroidTestingRunner;
56import android.testing.TestableLooper;
57import android.view.WindowManager;
Mady Mellorebdbbb92018-11-15 14:36:48 -080058
Brett Chabot84151d92019-02-27 15:37:59 -080059import androidx.test.filters.SmallTest;
60
Dave Mankoff2aff6c32019-10-14 17:40:37 -040061import com.android.internal.colorextraction.ColorExtractor;
Heemin Seogafb3dbc2019-11-04 16:05:19 -080062import com.android.systemui.SystemUIFactory;
Mady Mellorebdbbb92018-11-15 14:36:48 -080063import com.android.systemui.SysuiTestCase;
Dave Mankoff2aff6c32019-10-14 17:40:37 -040064import com.android.systemui.colorextraction.SysuiColorExtractor;
Ned Burnsaaeb44b2020-02-12 23:48:26 -050065import com.android.systemui.dump.DumpManager;
Joshua Tsujibe60a582020-03-23 17:17:26 -040066import com.android.systemui.model.SysUiState;
Mady Mellorc55b4122019-06-07 18:14:02 -070067import com.android.systemui.plugins.statusbar.StatusBarStateController;
Joshua Tsujibe60a582020-03-23 17:17:26 -040068import com.android.systemui.shared.system.QuickStepContract;
Beverlya53fb0d2020-01-29 15:26:13 -050069import com.android.systemui.statusbar.FeatureFlags;
Mark Renoufc19b4732019-06-26 12:08:33 -040070import com.android.systemui.statusbar.NotificationLockscreenUserManager;
Mady Mellorc2ff0112019-03-28 14:18:06 -070071import com.android.systemui.statusbar.NotificationRemoveInterceptor;
Mady Mellor76343012020-05-13 11:02:50 -070072import com.android.systemui.statusbar.RankingBuilder;
Heemin Seogafb3dbc2019-11-04 16:05:19 -080073import com.android.systemui.statusbar.SuperStatusBarViewFactory;
Lucas Dupine25c4872019-07-29 13:51:35 -070074import com.android.systemui.statusbar.SysuiStatusBarStateController;
Ned Burns01e38212019-01-03 16:32:52 -050075import com.android.systemui.statusbar.notification.NotificationEntryListener;
76import com.android.systemui.statusbar.notification.NotificationEntryManager;
Mady Mellorc55b4122019-06-07 18:14:02 -070077import com.android.systemui.statusbar.notification.NotificationFilter;
Beverlya53fb0d2020-01-29 15:26:13 -050078import com.android.systemui.statusbar.notification.collection.NotifPipeline;
Mady Mellor8d25b202019-06-25 13:59:28 -070079import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Dave Mankoff56fe9e42020-01-08 15:42:06 -050080import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
Mady Mellorebdbbb92018-11-15 14:36:48 -080081import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
Kevin Han933dc7c2020-01-29 11:17:46 -080082import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
Dave Mankoff56fe9e42020-01-08 15:42:06 -050083import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
Mady Mellorebdbbb92018-11-15 14:36:48 -080084import com.android.systemui.statusbar.phone.DozeParameters;
Lucas Dupine25c4872019-07-29 13:51:35 -070085import com.android.systemui.statusbar.phone.KeyguardBypassController;
Dave Mankoffc0d9a7d2020-02-27 17:15:52 -050086import com.android.systemui.statusbar.phone.LockscreenLockIconController;
Ned Burns296aec162019-09-04 17:30:59 -040087import com.android.systemui.statusbar.phone.NotificationGroupManager;
wilsonshihe8321942019-10-18 18:39:46 +080088import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
Fabian Kozynskib00c70b2020-04-03 12:41:31 -040089import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
Mady Mellor7f234902019-10-20 12:06:29 -070090import com.android.systemui.statusbar.phone.ShadeController;
Lucas Dupinbd7366d2019-09-25 13:39:21 -070091import com.android.systemui.statusbar.policy.BatteryController;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -070092import com.android.systemui.statusbar.policy.ConfigurationController;
Mady Melloraa8fef22019-04-11 13:36:40 -070093import com.android.systemui.statusbar.policy.HeadsUpManager;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -040094import com.android.systemui.statusbar.policy.ZenModeController;
Joshua Tsuji7155bf12020-02-13 16:14:29 -050095import com.android.systemui.util.FloatingContentCoordinator;
Heemin Seogafb3dbc2019-11-04 16:05:19 -080096import com.android.systemui.util.InjectionInflationController;
Mady Mellorebdbbb92018-11-15 14:36:48 -080097
Lyn Han89274b42020-03-25 00:56:26 -070098import com.google.common.collect.ImmutableList;
99
Mady Mellorebdbbb92018-11-15 14:36:48 -0800100import org.junit.Before;
101import org.junit.Test;
102import org.junit.runner.RunWith;
Ned Burns01e38212019-01-03 16:32:52 -0500103import org.mockito.ArgumentCaptor;
104import org.mockito.Captor;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800105import org.mockito.Mock;
106import org.mockito.MockitoAnnotations;
107
Beverlya53fb0d2020-01-29 15:26:13 -0500108import java.util.List;
109
110/**
111 * Tests the NotificationEntryManager setup with BubbleController.
112 * The {@link NotifPipeline} setup with BubbleController is tested in
113 * {@link NewNotifPipelineBubbleControllerTest}.
114 */
Mady Mellorebdbbb92018-11-15 14:36:48 -0800115@SmallTest
116@RunWith(AndroidTestingRunner.class)
117@TestableLooper.RunWithLooper(setAsMainLooper = true)
118public class BubbleControllerTest extends SysuiTestCase {
Mady Mellorebdbbb92018-11-15 14:36:48 -0800119 @Mock
Ned Burns01e38212019-01-03 16:32:52 -0500120 private NotificationEntryManager mNotificationEntryManager;
121 @Mock
Mady Mellor22f2f072019-04-18 13:26:18 -0700122 private NotificationGroupManager mNotificationGroupManager;
123 @Mock
Mady Mellorebdbbb92018-11-15 14:36:48 -0800124 private WindowManager mWindowManager;
125 @Mock
126 private IActivityManager mActivityManager;
127 @Mock
128 private DozeParameters mDozeParameters;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -0700129 @Mock
130 private ConfigurationController mConfigurationController;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -0400131 @Mock
132 private ZenModeController mZenModeController;
133 @Mock
134 private ZenModeConfig mZenModeConfig;
Mady Mellor80c25b22019-06-17 14:40:37 -0700135 @Mock
136 private FaceManager mFaceManager;
Mark Renoufc19b4732019-06-26 12:08:33 -0400137 @Mock
138 private NotificationLockscreenUserManager mLockscreenUserManager;
Mady Mellorf474e0d2019-08-01 11:08:40 -0700139 @Mock
Lucas Dupine25c4872019-07-29 13:51:35 -0700140 private SysuiStatusBarStateController mStatusBarStateController;
141 @Mock
142 private KeyguardBypassController mKeyguardBypassController;
Joshua Tsuji7155bf12020-02-13 16:14:29 -0500143 @Mock
144 private FloatingContentCoordinator mFloatingContentCoordinator;
Pinyao Tingee191b12020-04-29 18:35:39 -0700145 @Mock
146 private BubbleDataRepository mDataRepository;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -0700147
Joshua Tsujibe60a582020-03-23 17:17:26 -0400148 private SysUiState mSysUiState;
149 private boolean mSysUiStateBubblesExpanded;
150
Ned Burns01e38212019-01-03 16:32:52 -0500151 @Captor
152 private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
Mady Mellorc2ff0112019-03-28 14:18:06 -0700153 @Captor
154 private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800155
156 private TestableBubbleController mBubbleController;
wilsonshihe8321942019-10-18 18:39:46 +0800157 private NotificationShadeWindowController mNotificationShadeWindowController;
Ned Burns01e38212019-01-03 16:32:52 -0500158 private NotificationEntryListener mEntryListener;
Mady Mellorc2ff0112019-03-28 14:18:06 -0700159 private NotificationRemoveInterceptor mRemoveInterceptor;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800160
161 private NotificationTestHelper mNotificationTestHelper;
162 private ExpandableNotificationRow mRow;
163 private ExpandableNotificationRow mRow2;
Lyn Han2f6e89d2020-04-15 10:01:01 -0700164 private ExpandableNotificationRow mRow3;
Mady Mellorfc02cc32019-04-01 14:47:55 -0700165 private ExpandableNotificationRow mNonBubbleNotifRow;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800166
Mady Mellorb4991e62019-01-10 15:14:51 -0800167 @Mock
Mady Melloracb12152019-01-29 15:24:48 -0800168 private BubbleController.BubbleExpandListener mBubbleExpandListener;
Mark Renouf6b2331c2019-03-21 13:40:08 -0400169 @Mock
Mark Renouf08bc42a2019-03-07 13:01:59 -0500170 private PendingIntent mDeleteIntent;
Dave Mankoff2aff6c32019-10-14 17:40:37 -0400171 @Mock
172 private SysuiColorExtractor mColorExtractor;
173 @Mock
174 ColorExtractor.GradientColors mGradientColors;
Heemin Seogafb3dbc2019-11-04 16:05:19 -0800175 @Mock
176 private Resources mResources;
Mady Mellor7f234902019-10-20 12:06:29 -0700177 @Mock
Heemin Seogba6337f2019-12-10 15:34:37 -0800178 private ShadeController mShadeController;
Aran Inkaa4dfa72019-11-18 16:49:07 -0500179 @Mock
Dave Mankoff56fe9e42020-01-08 15:42:06 -0500180 private NotificationRowComponent mNotificationRowComponent;
Beverlya53fb0d2020-01-29 15:26:13 -0500181 @Mock
182 private NotifPipeline mNotifPipeline;
183 @Mock
184 private FeatureFlags mFeatureFlagsOldPipeline;
185 @Mock
Ned Burnsaaeb44b2020-02-12 23:48:26 -0500186 private DumpManager mDumpManager;
Dave Mankoffc0d9a7d2020-02-27 17:15:52 -0500187 @Mock
188 private LockscreenLockIconController mLockIconController;
Fabian Kozynskib00c70b2020-04-03 12:41:31 -0400189 @Mock
190 private NotificationShadeWindowView mNotificationShadeWindowView;
Mark Renouf08bc42a2019-03-07 13:01:59 -0500191
Heemin Seogafb3dbc2019-11-04 16:05:19 -0800192 private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
Mady Mellorcfd06c12019-02-13 14:32:12 -0800193 private BubbleData mBubbleData;
194
Mady Mellorb8aaf972019-11-26 10:28:00 -0800195 private TestableLooper mTestableLooper;
196
Mady Mellorebdbbb92018-11-15 14:36:48 -0800197 @Before
198 public void setUp() throws Exception {
199 MockitoAnnotations.initMocks(this);
Mady Mellorb8aaf972019-11-26 10:28:00 -0800200
201 mTestableLooper = TestableLooper.get(this);
202
Mady Mellor80c25b22019-06-17 14:40:37 -0700203 mContext.addMockSystemService(FaceManager.class, mFaceManager);
Dave Mankoff2aff6c32019-10-14 17:40:37 -0400204 when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800205
Heemin Seogafb3dbc2019-11-04 16:05:19 -0800206 mSuperStatusBarViewFactory = new SuperStatusBarViewFactory(mContext,
Dave Mankoff56fe9e42020-01-08 15:42:06 -0500207 new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()),
208 new NotificationRowComponent.Builder() {
209 @Override
210 public NotificationRowComponent.Builder activatableNotificationView(
211 ActivatableNotificationView view) {
212 return this;
213 }
214
215 @Override
216 public NotificationRowComponent build() {
217 return mNotificationRowComponent;
218 }
Dave Mankoffc0d9a7d2020-02-27 17:15:52 -0500219 },
220 mLockIconController);
Heemin Seogafb3dbc2019-11-04 16:05:19 -0800221
Mady Mellorebdbbb92018-11-15 14:36:48 -0800222 // Bubbles get added to status bar window view
wilsonshihe8321942019-10-18 18:39:46 +0800223 mNotificationShadeWindowController = new NotificationShadeWindowController(mContext,
224 mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
Lucas Dupind73410a2020-02-18 12:54:41 -0800225 mConfigurationController, mKeyguardBypassController, mColorExtractor,
Ned Burnsaaeb44b2020-02-12 23:48:26 -0500226 mDumpManager);
Fabian Kozynskib00c70b2020-04-03 12:41:31 -0400227 mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
wilsonshihe8321942019-10-18 18:39:46 +0800228 mNotificationShadeWindowController.attach();
Mady Mellorebdbbb92018-11-15 14:36:48 -0800229
230 // Need notifications for bubbles
Kevin Hana7c21be2020-04-01 17:58:35 -0700231 mNotificationTestHelper = new NotificationTestHelper(
232 mContext,
233 mDependency,
234 TestableLooper.get(this));
Mark Renouf08bc42a2019-03-07 13:01:59 -0500235 mRow = mNotificationTestHelper.createBubble(mDeleteIntent);
236 mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700237 mRow3 = mNotificationTestHelper.createBubble(mDeleteIntent);
Mady Mellorfc02cc32019-04-01 14:47:55 -0700238 mNonBubbleNotifRow = mNotificationTestHelper.createRow();
Mady Mellor3ed46202019-03-26 20:22:35 -0700239
Ned Burns01e38212019-01-03 16:32:52 -0500240 // Return non-null notification data from the NEM
Evan Laird181de622019-10-24 09:53:02 -0400241 when(mNotificationEntryManager
242 .getActiveNotificationUnfiltered(mRow.getEntry().getKey())).thenReturn(
243 mRow.getEntry());
Ned Burns01e38212019-01-03 16:32:52 -0500244
Joshua Tsujidd4d9f92019-05-13 13:57:38 -0400245 mZenModeConfig.suppressedVisualEffects = 0;
246 when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
247
Joshua Tsujibe60a582020-03-23 17:17:26 -0400248 mSysUiState = new SysUiState();
249 mSysUiState.addCallback(sysUiFlags ->
250 mSysUiStateBubblesExpanded =
251 (sysUiFlags & QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED) != 0);
252
Beverly Taid1e175c2020-03-10 16:37:04 +0000253 TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
254 new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
255 mock(PowerManager.class),
256 mock(IDreamManager.class),
257 mock(AmbientDisplayConfiguration.class),
Mady Mellorc55b4122019-06-07 18:14:02 -0700258 mock(NotificationFilter.class),
Lucas Dupinbd7366d2019-09-25 13:39:21 -0700259 mock(StatusBarStateController.class),
Beverly Taid1e175c2020-03-10 16:37:04 +0000260 mock(BatteryController.class),
261 mock(HeadsUpManager.class),
262 mock(Handler.class)
263 );
Mark Renouf71a3af62019-04-08 15:02:54 -0400264 mBubbleData = new BubbleData(mContext);
Beverlya53fb0d2020-01-29 15:26:13 -0500265 when(mFeatureFlagsOldPipeline.isNewNotifPipelineRenderingEnabled()).thenReturn(false);
Ned Burnsaaeb44b2020-02-12 23:48:26 -0500266 mBubbleController = new TestableBubbleController(
267 mContext,
wilsonshihe8321942019-10-18 18:39:46 +0800268 mNotificationShadeWindowController,
Mady Mellor7f234902019-10-20 12:06:29 -0700269 mStatusBarStateController,
270 mShadeController,
Mady Mellor22f2f072019-04-18 13:26:18 -0700271 mBubbleData,
272 mConfigurationController,
273 interruptionStateProvider,
274 mZenModeController,
275 mLockscreenUserManager,
Mady Mellor7f234902019-10-20 12:06:29 -0700276 mNotificationGroupManager,
Beverlya53fb0d2020-01-29 15:26:13 -0500277 mNotificationEntryManager,
278 mNotifPipeline,
279 mFeatureFlagsOldPipeline,
Ned Burnsaaeb44b2020-02-12 23:48:26 -0500280 mDumpManager,
Joshua Tsujibe60a582020-03-23 17:17:26 -0400281 mFloatingContentCoordinator,
Pinyao Tingee191b12020-04-29 18:35:39 -0700282 mDataRepository,
Mady Mellor9adfe6a2020-03-30 17:23:26 -0700283 mSysUiState,
Mady Mellor59a7b982020-05-11 15:19:59 -0700284 mock(INotificationManager.class),
285 mWindowManager);
Mady Melloracb12152019-01-29 15:24:48 -0800286 mBubbleController.setExpandListener(mBubbleExpandListener);
Ned Burns01e38212019-01-03 16:32:52 -0500287
288 // Get a reference to the BubbleController's entry listener
289 verify(mNotificationEntryManager, atLeastOnce())
290 .addNotificationEntryListener(mEntryListenerCaptor.capture());
291 mEntryListener = mEntryListenerCaptor.getValue();
Mady Mellorc2ff0112019-03-28 14:18:06 -0700292 // And the remove interceptor
293 verify(mNotificationEntryManager, atLeastOnce())
Evan Laird04373662020-01-24 17:37:39 -0500294 .addNotificationRemoveInterceptor(mRemoveInterceptorCaptor.capture());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700295 mRemoveInterceptor = mRemoveInterceptorCaptor.getValue();
Mady Mellorebdbbb92018-11-15 14:36:48 -0800296 }
297
298 @Test
Mady Mellorebdbbb92018-11-15 14:36:48 -0800299 public void testAddBubble() {
Mark Renouff97ed462019-04-05 13:46:24 -0400300 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800301 assertTrue(mBubbleController.hasBubbles());
Mady Melloracb12152019-01-29 15:24:48 -0800302
Joshua Tsujibe60a582020-03-23 17:17:26 -0400303 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800304 }
305
306 @Test
307 public void testHasBubbles() {
308 assertFalse(mBubbleController.hasBubbles());
Mark Renouff97ed462019-04-05 13:46:24 -0400309 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800310 assertTrue(mBubbleController.hasBubbles());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400311 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800312 }
313
314 @Test
315 public void testRemoveBubble() {
Mark Renouff97ed462019-04-05 13:46:24 -0400316 mBubbleController.updateBubble(mRow.getEntry());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700317 assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Mady Mellorebdbbb92018-11-15 14:36:48 -0800318 assertTrue(mBubbleController.hasBubbles());
Beverly85d4c192019-09-30 11:40:39 -0400319 verify(mNotificationEntryManager).updateNotifications(any());
Mady Melloracb12152019-01-29 15:24:48 -0800320
Ned Burns00b4b2d2019-10-17 22:09:27 -0400321 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000322 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700323 assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Beverly85d4c192019-09-30 11:40:39 -0400324 verify(mNotificationEntryManager, times(2)).updateNotifications(anyString());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400325
326 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800327 }
328
329 @Test
Lyn Han89274b42020-03-25 00:56:26 -0700330 public void testPromoteBubble_autoExpand() {
331 mBubbleController.updateBubble(mRow2.getEntry());
332 mBubbleController.updateBubble(mRow.getEntry());
333 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000334 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Lyn Han89274b42020-03-25 00:56:26 -0700335
336 Bubble b = mBubbleData.getOverflowBubbleWithKey(mRow.getEntry().getKey());
337 assertThat(mBubbleData.getOverflowBubbles()).isEqualTo(ImmutableList.of(b));
Lyn Han2f6e89d2020-04-15 10:01:01 -0700338 verify(mNotificationEntryManager, never()).performRemoveNotification(
339 eq(mRow.getEntry().getSbn()), anyInt());
340 assertFalse(mRow.getEntry().isBubble());
Lyn Han89274b42020-03-25 00:56:26 -0700341
Lyn Han2f6e89d2020-04-15 10:01:01 -0700342 Bubble b2 = mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey());
Lyn Han89274b42020-03-25 00:56:26 -0700343 assertThat(mBubbleData.getSelectedBubble()).isEqualTo(b2);
344
345 mBubbleController.promoteBubbleFromOverflow(b);
346 assertThat(mBubbleData.getSelectedBubble()).isEqualTo(b);
347 }
348
349 @Test
Lyn Han2f6e89d2020-04-15 10:01:01 -0700350 public void testCancelOverflowBubble() {
351 mBubbleController.updateBubble(mRow2.getEntry());
352 mBubbleController.updateBubble(mRow.getEntry(), /* suppressFlyout */
353 false, /* showInShade */ true);
Ned Burns00b4b2d2019-10-17 22:09:27 -0400354 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000355 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700356
Pinyao Ting3c930612020-05-19 00:26:03 +0000357 mBubbleController.removeBubble(
358 mRow.getEntry().getKey(), BubbleController.DISMISS_NOTIF_CANCEL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700359 verify(mNotificationEntryManager, times(1)).performRemoveNotification(
Beverlya53fb0d2020-01-29 15:26:13 -0500360 eq(mRow.getEntry().getSbn()), anyInt());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700361 assertThat(mBubbleData.getOverflowBubbles()).isEmpty();
362 assertFalse(mRow.getEntry().isBubble());
363 }
Joshua Tsujibe60a582020-03-23 17:17:26 -0400364
Lyn Han2f6e89d2020-04-15 10:01:01 -0700365 @Test
366 public void testUserChange_doesNotRemoveNotif() {
367 mBubbleController.updateBubble(mRow.getEntry());
368 assertTrue(mBubbleController.hasBubbles());
369
370 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000371 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_CHANGED);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700372 verify(mNotificationEntryManager, never()).performRemoveNotification(
373 eq(mRow.getEntry().getSbn()), anyInt());
374 assertFalse(mBubbleController.hasBubbles());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400375 assertFalse(mSysUiStateBubblesExpanded);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700376 assertTrue(mRow.getEntry().isBubble());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700377 }
378
379 @Test
Mady Mellorebdbbb92018-11-15 14:36:48 -0800380 public void testDismissStack() {
Mark Renouff97ed462019-04-05 13:46:24 -0400381 mBubbleController.updateBubble(mRow.getEntry());
Beverly85d4c192019-09-30 11:40:39 -0400382 verify(mNotificationEntryManager, times(1)).updateNotifications(any());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700383 assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Mark Renouff97ed462019-04-05 13:46:24 -0400384 mBubbleController.updateBubble(mRow2.getEntry());
Beverly85d4c192019-09-30 11:40:39 -0400385 verify(mNotificationEntryManager, times(2)).updateNotifications(any());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700386 assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey()));
Mady Mellorebdbbb92018-11-15 14:36:48 -0800387 assertTrue(mBubbleController.hasBubbles());
388
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400389 mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE);
Beverly85d4c192019-09-30 11:40:39 -0400390 verify(mNotificationEntryManager, times(3)).updateNotifications(any());
Lyn Han2f6e89d2020-04-15 10:01:01 -0700391 assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
392 assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey()));
Joshua Tsujibe60a582020-03-23 17:17:26 -0400393
394 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800395 }
396
397 @Test
Mady Melloracb12152019-01-29 15:24:48 -0800398 public void testExpandCollapseStack() {
Mady Mellorebdbbb92018-11-15 14:36:48 -0800399 assertFalse(mBubbleController.isStackExpanded());
Mady Melloracb12152019-01-29 15:24:48 -0800400
401 // Mark it as a bubble and add it explicitly
Mady Mellor78133512020-01-31 08:45:52 -0800402 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400403 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800404
Mady Mellorce23c462019-06-17 17:30:07 -0700405 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800406 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400407 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500408 mRow.getEntry()));
Mady Melloracb12152019-01-29 15:24:48 -0800409
410 // Expand the stack
Mady Mellorebdbbb92018-11-15 14:36:48 -0800411 BubbleStackView stackView = mBubbleController.getStackView();
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400412 mBubbleData.setExpanded(true);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800413 assertTrue(mBubbleController.isStackExpanded());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400414 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800415
Joshua Tsujibe60a582020-03-23 17:17:26 -0400416 assertTrue(mSysUiStateBubblesExpanded);
417
Mady Mellorce23c462019-06-17 17:30:07 -0700418 // Make sure the notif is suppressed
Ned Burns00b4b2d2019-10-17 22:09:27 -0400419 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500420 mRow.getEntry()));
Mady Melloracb12152019-01-29 15:24:48 -0800421
422 // Collapse
Mark Renouf71a3af62019-04-08 15:02:54 -0400423 mBubbleController.collapseStack();
Ned Burns00b4b2d2019-10-17 22:09:27 -0400424 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800425 assertFalse(mBubbleController.isStackExpanded());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400426
427 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800428 }
429
430 @Test
Mady Melloracb12152019-01-29 15:24:48 -0800431 public void testCollapseAfterChangingExpandedBubble() {
432 // Mark it as a bubble and add it explicitly
Mady Mellor78133512020-01-31 08:45:52 -0800433 mEntryListener.onPendingEntryAdded(mRow.getEntry());
434 mEntryListener.onPendingEntryAdded(mRow2.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400435 mBubbleController.updateBubble(mRow.getEntry());
436 mBubbleController.updateBubble(mRow2.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800437
Mady Mellorce23c462019-06-17 17:30:07 -0700438 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800439 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700440 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500441 mRow.getEntry()));
Ned Burns00b4b2d2019-10-17 22:09:27 -0400442 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500443 mRow2.getEntry()));
Mady Melloracb12152019-01-29 15:24:48 -0800444
445 // Expand
Mady Mellorebdbbb92018-11-15 14:36:48 -0800446 BubbleStackView stackView = mBubbleController.getStackView();
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400447 mBubbleData.setExpanded(true);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800448 assertTrue(mBubbleController.isStackExpanded());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400449 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800450
Joshua Tsujibe60a582020-03-23 17:17:26 -0400451 assertTrue(mSysUiStateBubblesExpanded);
452
Mark Renoufba5ab512019-05-02 15:21:01 -0400453 // Last added is the one that is expanded
Mady Mellorb8aaf972019-11-26 10:28:00 -0800454 assertEquals(mRow2.getEntry(), mBubbleData.getSelectedBubble().getEntry());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400455 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500456 mRow2.getEntry()));
Mark Renouf71a3af62019-04-08 15:02:54 -0400457
Mark Renoufba5ab512019-05-02 15:21:01 -0400458 // Switch which bubble is expanded
Lyn Han2f6e89d2020-04-15 10:01:01 -0700459 mBubbleData.setSelectedBubble(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800460 mBubbleData.setExpanded(true);
Lyn Han9f66c3b2020-03-05 23:59:29 -0800461 assertEquals(mRow.getEntry(),
Lyn Han2f6e89d2020-04-15 10:01:01 -0700462 mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey()).getEntry());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400463 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500464 mRow.getEntry()));
Mark Renoufba5ab512019-05-02 15:21:01 -0400465
Mady Melloracb12152019-01-29 15:24:48 -0800466 // collapse for previous bubble
Ned Burns00b4b2d2019-10-17 22:09:27 -0400467 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800468 // expand for selected bubble
Ned Burns00b4b2d2019-10-17 22:09:27 -0400469 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
Mady Melloredd4ee12019-01-18 10:45:11 -0800470
Mady Melloracb12152019-01-29 15:24:48 -0800471 // Collapse
Mady Mellorebdbbb92018-11-15 14:36:48 -0800472 mBubbleController.collapseStack();
473 assertFalse(mBubbleController.isStackExpanded());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400474
475 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800476 }
477
Ned Burns01e38212019-01-03 16:32:52 -0500478 @Test
Mady Melloraea895f02019-07-10 14:37:48 -0700479 public void testExpansionRemovesShowInShadeAndDot() {
Mady Melloracb12152019-01-29 15:24:48 -0800480 // Mark it as a bubble and add it explicitly
Mady Mellor78133512020-01-31 08:45:52 -0800481 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400482 mBubbleController.updateBubble(mRow.getEntry());
Mady Melloracb12152019-01-29 15:24:48 -0800483
Mady Mellorce23c462019-06-17 17:30:07 -0700484 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800485 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400486 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500487 mRow.getEntry()));
Mady Mellorb8aaf972019-11-26 10:28:00 -0800488
489 mTestableLooper.processAllMessages();
Lyn Han2f6e89d2020-04-15 10:01:01 -0700490 assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Melloracb12152019-01-29 15:24:48 -0800491
492 // Expand
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400493 mBubbleData.setExpanded(true);
Mady Melloracb12152019-01-29 15:24:48 -0800494 assertTrue(mBubbleController.isStackExpanded());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400495 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800496
Joshua Tsujibe60a582020-03-23 17:17:26 -0400497 assertTrue(mSysUiStateBubblesExpanded);
498
Mady Mellorce23c462019-06-17 17:30:07 -0700499 // Notif is suppressed after expansion
Ned Burns00b4b2d2019-10-17 22:09:27 -0400500 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500501 mRow.getEntry()));
Mady Melloraea895f02019-07-10 14:37:48 -0700502 // Notif shouldn't show dot after expansion
Lyn Han2f6e89d2020-04-15 10:01:01 -0700503 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Melloraea895f02019-07-10 14:37:48 -0700504 }
505
506 @Test
507 public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() {
508 // Mark it as a bubble and add it explicitly
Mady Mellor78133512020-01-31 08:45:52 -0800509 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Melloraea895f02019-07-10 14:37:48 -0700510 mBubbleController.updateBubble(mRow.getEntry());
511
512 // We should have bubbles & their notifs should not be suppressed
513 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400514 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500515 mRow.getEntry()));
Mady Mellorb8aaf972019-11-26 10:28:00 -0800516
517 mTestableLooper.processAllMessages();
Lyn Han2f6e89d2020-04-15 10:01:01 -0700518 assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Melloraea895f02019-07-10 14:37:48 -0700519
520 // Expand
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400521 mBubbleData.setExpanded(true);
Mady Melloraea895f02019-07-10 14:37:48 -0700522 assertTrue(mBubbleController.isStackExpanded());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400523 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
Mady Melloraea895f02019-07-10 14:37:48 -0700524
Joshua Tsujibe60a582020-03-23 17:17:26 -0400525 assertTrue(mSysUiStateBubblesExpanded);
526
Mady Melloraea895f02019-07-10 14:37:48 -0700527 // Notif is suppressed after expansion
Ned Burns00b4b2d2019-10-17 22:09:27 -0400528 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500529 mRow.getEntry()));
Mady Melloraea895f02019-07-10 14:37:48 -0700530 // Notif shouldn't show dot after expansion
Lyn Han2f6e89d2020-04-15 10:01:01 -0700531 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Melloraea895f02019-07-10 14:37:48 -0700532
533 // Send update
534 mEntryListener.onPreEntryUpdated(mRow.getEntry());
535
536 // Nothing should have changed
537 // Notif is suppressed after expansion
Ned Burns00b4b2d2019-10-17 22:09:27 -0400538 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500539 mRow.getEntry()));
Mady Melloraea895f02019-07-10 14:37:48 -0700540 // Notif shouldn't show dot after expansion
Lyn Han2f6e89d2020-04-15 10:01:01 -0700541 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Melloracb12152019-01-29 15:24:48 -0800542 }
543
544 @Test
545 public void testRemoveLastExpandedCollapses() {
546 // Mark it as a bubble and add it explicitly
Mady Mellor78133512020-01-31 08:45:52 -0800547 mEntryListener.onPendingEntryAdded(mRow.getEntry());
548 mEntryListener.onPendingEntryAdded(mRow2.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400549 mBubbleController.updateBubble(mRow.getEntry());
550 mBubbleController.updateBubble(mRow2.getEntry());
Mady Melloracb12152019-01-29 15:24:48 -0800551
552 // Expand
553 BubbleStackView stackView = mBubbleController.getStackView();
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400554 mBubbleData.setExpanded(true);
Mady Melloracb12152019-01-29 15:24:48 -0800555
Joshua Tsujibe60a582020-03-23 17:17:26 -0400556 assertTrue(mSysUiStateBubblesExpanded);
557
Mady Melloracb12152019-01-29 15:24:48 -0800558 assertTrue(mBubbleController.isStackExpanded());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400559 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800560
Mark Renoufba5ab512019-05-02 15:21:01 -0400561 // Last added is the one that is expanded
Lyn Han9f66c3b2020-03-05 23:59:29 -0800562 assertEquals(mRow2.getEntry(),
Lyn Han2f6e89d2020-04-15 10:01:01 -0700563 mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey()).getEntry());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400564 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500565 mRow2.getEntry()));
Mady Melloracb12152019-01-29 15:24:48 -0800566
567 // Dismiss currently expanded
Lyn Han9f66c3b2020-03-05 23:59:29 -0800568 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000569 mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey())
570 .getEntry().getKey(),
Mark Renouf08bc42a2019-03-07 13:01:59 -0500571 BubbleController.DISMISS_USER_GESTURE);
Ned Burns00b4b2d2019-10-17 22:09:27 -0400572 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800573
Mark Renoufba5ab512019-05-02 15:21:01 -0400574 // Make sure first bubble is selected
Lyn Han9f66c3b2020-03-05 23:59:29 -0800575 assertEquals(mRow.getEntry(),
Lyn Han2f6e89d2020-04-15 10:01:01 -0700576 mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey()).getEntry());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400577 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800578
579 // Dismiss that one
Lyn Han9f66c3b2020-03-05 23:59:29 -0800580 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000581 mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey())
582 .getEntry().getKey(),
Mark Renouf08bc42a2019-03-07 13:01:59 -0500583 BubbleController.DISMISS_USER_GESTURE);
Mady Melloracb12152019-01-29 15:24:48 -0800584
585 // Make sure state changes and collapse happens
Ned Burns00b4b2d2019-10-17 22:09:27 -0400586 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
Mady Melloracb12152019-01-29 15:24:48 -0800587 assertFalse(mBubbleController.hasBubbles());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400588
589 assertFalse(mSysUiStateBubblesExpanded);
Mady Melloracb12152019-01-29 15:24:48 -0800590 }
591
592 @Test
Mady Mellorb25f9062019-12-09 12:12:57 -0800593 public void testAutoExpand_fails_noFlag() {
Mady Mellore80930e2019-03-21 16:00:45 -0700594 assertFalse(mBubbleController.isStackExpanded());
Mady Mellor8d25b202019-06-25 13:59:28 -0700595 setMetadataFlags(mRow.getEntry(),
596 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, false /* enableFlag */);
Mady Mellore80930e2019-03-21 16:00:45 -0700597
598 // Add the auto expand bubble
Mady Mellor78133512020-01-31 08:45:52 -0800599 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellor8d25b202019-06-25 13:59:28 -0700600 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellore80930e2019-03-21 16:00:45 -0700601
602 // Expansion shouldn't change
603 verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */,
Ned Burns00b4b2d2019-10-17 22:09:27 -0400604 mRow.getEntry().getKey());
Mady Mellore80930e2019-03-21 16:00:45 -0700605 assertFalse(mBubbleController.isStackExpanded());
606
Joshua Tsujibe60a582020-03-23 17:17:26 -0400607 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellore80930e2019-03-21 16:00:45 -0700608 }
609
610 @Test
Mady Mellorb25f9062019-12-09 12:12:57 -0800611 public void testAutoExpand_succeeds_withFlag() {
Mady Mellor8d25b202019-06-25 13:59:28 -0700612 setMetadataFlags(mRow.getEntry(),
613 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */);
Mady Mellore80930e2019-03-21 16:00:45 -0700614
615 // Add the auto expand bubble
Mady Mellor78133512020-01-31 08:45:52 -0800616 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellor8d25b202019-06-25 13:59:28 -0700617 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellore80930e2019-03-21 16:00:45 -0700618
619 // Expansion should change
620 verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */,
Ned Burns00b4b2d2019-10-17 22:09:27 -0400621 mRow.getEntry().getKey());
Mady Mellore80930e2019-03-21 16:00:45 -0700622 assertTrue(mBubbleController.isStackExpanded());
623
Joshua Tsujibe60a582020-03-23 17:17:26 -0400624 assertTrue(mSysUiStateBubblesExpanded);
Mady Mellore80930e2019-03-21 16:00:45 -0700625 }
626
Mady Mellor3ed46202019-03-26 20:22:35 -0700627 @Test
Mady Mellorb25f9062019-12-09 12:12:57 -0800628 public void testSuppressNotif_onInitialNotif() {
Mady Mellor8d25b202019-06-25 13:59:28 -0700629 setMetadataFlags(mRow.getEntry(),
630 Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */);
Mady Mellor3ed46202019-03-26 20:22:35 -0700631
632 // Add the suppress notif bubble
Mady Mellor78133512020-01-31 08:45:52 -0800633 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellor8d25b202019-06-25 13:59:28 -0700634 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellor3ed46202019-03-26 20:22:35 -0700635
Mady Mellorce23c462019-06-17 17:30:07 -0700636 // Notif should be suppressed because we were foreground
Ned Burns00b4b2d2019-10-17 22:09:27 -0400637 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500638 mRow.getEntry()));
Mady Mellorb25f9062019-12-09 12:12:57 -0800639 // Dot + flyout is hidden because notif is suppressed
Lyn Han2f6e89d2020-04-15 10:01:01 -0700640 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
641 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout());
Mady Mellor3ed46202019-03-26 20:22:35 -0700642
Joshua Tsujibe60a582020-03-23 17:17:26 -0400643 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellor3ed46202019-03-26 20:22:35 -0700644 }
Mady Mellore80930e2019-03-21 16:00:45 -0700645
646 @Test
Mady Mellorb25f9062019-12-09 12:12:57 -0800647 public void testSuppressNotif_onUpdateNotif() {
648 mBubbleController.updateBubble(mRow.getEntry());
649
650 // Should not be suppressed
651 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500652 mRow.getEntry()));
Mady Mellorb25f9062019-12-09 12:12:57 -0800653 // Should show dot
Lyn Han2f6e89d2020-04-15 10:01:01 -0700654 assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Mellorb25f9062019-12-09 12:12:57 -0800655
656 // Update to suppress notif
657 setMetadataFlags(mRow.getEntry(),
658 Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */);
659 mBubbleController.updateBubble(mRow.getEntry());
660
661 // Notif should be suppressed
662 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500663 mRow.getEntry()));
Mady Mellorb25f9062019-12-09 12:12:57 -0800664 // Dot + flyout is hidden because notif is suppressed
Lyn Han2f6e89d2020-04-15 10:01:01 -0700665 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
666 assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout());
Mady Mellorb25f9062019-12-09 12:12:57 -0800667
Joshua Tsujibe60a582020-03-23 17:17:26 -0400668 assertFalse(mSysUiStateBubblesExpanded);
Mady Mellorb25f9062019-12-09 12:12:57 -0800669 }
670
Mady Mellorb25f9062019-12-09 12:12:57 -0800671 @Test
Mark Renouffec45da2019-03-13 13:24:27 -0400672 public void testExpandStackAndSelectBubble_removedFirst() {
Ned Burns00b4b2d2019-10-17 22:09:27 -0400673 final String key = mRow.getEntry().getKey();
Mark Renouffec45da2019-03-13 13:24:27 -0400674
Mady Mellor78133512020-01-31 08:45:52 -0800675 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400676 mBubbleController.updateBubble(mRow.getEntry());
Mark Renouffec45da2019-03-13 13:24:27 -0400677
Mark Renouffec45da2019-03-13 13:24:27 -0400678 // Simulate notification cancellation.
Ned Burns00b4b2d2019-10-17 22:09:27 -0400679 mRemoveInterceptor.onNotificationRemoveRequested(
Evan Laird04373662020-01-24 17:37:39 -0500680 mRow.getEntry().getKey(), mRow.getEntry(), REASON_APP_CANCEL);
Mark Renouffec45da2019-03-13 13:24:27 -0400681
Mady Mellor76343012020-05-13 11:02:50 -0700682 mBubbleController.expandStackAndSelectBubble(mRow.getEntry());
Joshua Tsujibe60a582020-03-23 17:17:26 -0400683
684 assertTrue(mSysUiStateBubblesExpanded);
Mark Renouffec45da2019-03-13 13:24:27 -0400685 }
686
687 @Test
Mady Mellor3f2efdb2018-11-21 11:30:45 -0800688 public void testMarkNewNotificationAsShowInShade() {
Mady Mellor78133512020-01-31 08:45:52 -0800689 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400690 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500691 mRow.getEntry()));
Mady Mellorb8aaf972019-11-26 10:28:00 -0800692
693 mTestableLooper.processAllMessages();
Lyn Han2f6e89d2020-04-15 10:01:01 -0700694 assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
Mady Mellor3f2efdb2018-11-21 11:30:45 -0800695 }
696
Mark Renouf08bc42a2019-03-07 13:01:59 -0500697 @Test
Mady Mellorfc02cc32019-04-01 14:47:55 -0700698 public void testAddNotif_notBubble() {
Mady Mellor78133512020-01-31 08:45:52 -0800699 mEntryListener.onPendingEntryAdded(mNonBubbleNotifRow.getEntry());
Mady Mellorfc02cc32019-04-01 14:47:55 -0700700 mEntryListener.onPreEntryUpdated(mNonBubbleNotifRow.getEntry());
701
Mady Mellorfc02cc32019-04-01 14:47:55 -0700702 assertThat(mBubbleController.hasBubbles()).isFalse();
703 }
704
705 @Test
Mark Renouf08bc42a2019-03-07 13:01:59 -0500706 public void testDeleteIntent_removeBubble_aged() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400707 mBubbleController.updateBubble(mRow.getEntry());
Pinyao Ting3c930612020-05-19 00:26:03 +0000708 mBubbleController.removeBubble(mRow.getEntry().getKey(), BubbleController.DISMISS_AGED);
Mark Renouf08bc42a2019-03-07 13:01:59 -0500709 verify(mDeleteIntent, never()).send();
710 }
711
712 @Test
713 public void testDeleteIntent_removeBubble_user() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400714 mBubbleController.updateBubble(mRow.getEntry());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400715 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000716 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Mark Renouf08bc42a2019-03-07 13:01:59 -0500717 verify(mDeleteIntent, times(1)).send();
718 }
719
720 @Test
721 public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400722 mBubbleController.updateBubble(mRow.getEntry());
723 mBubbleController.updateBubble(mRow2.getEntry());
Joshua Tsuji7dd88b02020-03-27 17:43:09 -0400724 mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE);
Mark Renouf08bc42a2019-03-07 13:01:59 -0500725 verify(mDeleteIntent, times(2)).send();
726 }
727
Mady Melloraa8fef22019-04-11 13:36:40 -0700728 @Test
729 public void testRemoveBubble_noLongerBubbleAfterUpdate()
730 throws PendingIntent.CanceledException {
731 mBubbleController.updateBubble(mRow.getEntry());
732 assertTrue(mBubbleController.hasBubbles());
733
Ned Burns00b4b2d2019-10-17 22:09:27 -0400734 mRow.getEntry().getSbn().getNotification().flags &= ~FLAG_BUBBLE;
Mady Mellor76343012020-05-13 11:02:50 -0700735 NotificationListenerService.Ranking ranking = new RankingBuilder(
736 mRow.getEntry().getRanking()).setCanBubble(false).build();
737 mRow.getEntry().setRanking(ranking);
Mady Melloraa8fef22019-04-11 13:36:40 -0700738 mEntryListener.onPreEntryUpdated(mRow.getEntry());
739
740 assertFalse(mBubbleController.hasBubbles());
741 verify(mDeleteIntent, never()).send();
742 }
743
Mady Mellorc2ff0112019-03-28 14:18:06 -0700744 @Test
745 public void testRemoveBubble_succeeds_appCancel() {
Mady Mellor78133512020-01-31 08:45:52 -0800746 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700747 mBubbleController.updateBubble(mRow.getEntry());
748
749 assertTrue(mBubbleController.hasBubbles());
750
751 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
Evan Laird04373662020-01-24 17:37:39 -0500752 mRow.getEntry().getKey(), mRow.getEntry(), REASON_APP_CANCEL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700753
754 // Cancels always remove so no need to intercept
755 assertFalse(intercepted);
Beverlya53fb0d2020-01-29 15:26:13 -0500756 }
757
758 @Test
759 public void testRemoveBubble_entryListenerRemove() {
760 mEntryListener.onPendingEntryAdded(mRow.getEntry());
761 mBubbleController.updateBubble(mRow.getEntry());
762
763 assertTrue(mBubbleController.hasBubbles());
764
765 // Removes the notification
Julia Reynolds138111f2020-02-26 11:17:39 -0500766 mEntryListener.onEntryRemoved(mRow.getEntry(), null, false, REASON_APP_CANCEL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700767 assertFalse(mBubbleController.hasBubbles());
768 }
769
770 @Test
Beverlya53fb0d2020-01-29 15:26:13 -0500771 public void removeBubble_clearAllIntercepted() {
Mady Mellor78133512020-01-31 08:45:52 -0800772 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700773 mBubbleController.updateBubble(mRow.getEntry());
774
775 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400776 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500777 mRow.getEntry()));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700778
779 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
Evan Laird04373662020-01-24 17:37:39 -0500780 mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL_ALL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700781
782 // Intercept!
783 assertTrue(intercepted);
784 // Should update show in shade state
Ned Burns00b4b2d2019-10-17 22:09:27 -0400785 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500786 mRow.getEntry()));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700787 }
788
789 @Test
Beverlya53fb0d2020-01-29 15:26:13 -0500790 public void removeBubble_userDismissNotifIntercepted() {
Mady Mellor78133512020-01-31 08:45:52 -0800791 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700792 mBubbleController.updateBubble(mRow.getEntry());
793
794 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400795 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500796 mRow.getEntry()));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700797
798 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
Evan Laird04373662020-01-24 17:37:39 -0500799 mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700800
801 // Intercept!
802 assertTrue(intercepted);
803 // Should update show in shade state
Ned Burns00b4b2d2019-10-17 22:09:27 -0400804 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500805 mRow.getEntry()));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700806 }
807
808 @Test
Lyn Han2f6e89d2020-04-15 10:01:01 -0700809 public void removeNotif_inOverflow_intercepted() {
810 // Get bubble with notif in shade.
811 mEntryListener.onPendingEntryAdded(mRow.getEntry());
812 mBubbleController.updateBubble(mRow.getEntry());
813 assertTrue(mBubbleController.hasBubbles());
814 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
815 mRow.getEntry()));
816
817 // Dismiss the bubble into overflow.
818 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000819 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700820 assertFalse(mBubbleController.hasBubbles());
821
822 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
823 mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL);
824
825 // Notif is no longer a bubble, but still in overflow, so we intercept removal.
826 assertTrue(intercepted);
827 }
828
829 @Test
830 public void removeNotif_notInOverflow_notIntercepted() {
831 // Get bubble with notif in shade.
Mady Mellor78133512020-01-31 08:45:52 -0800832 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorc2ff0112019-03-28 14:18:06 -0700833 mBubbleController.updateBubble(mRow.getEntry());
834
835 assertTrue(mBubbleController.hasBubbles());
Ned Burns00b4b2d2019-10-17 22:09:27 -0400836 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500837 mRow.getEntry()));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700838
Ned Burns00b4b2d2019-10-17 22:09:27 -0400839 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000840 mRow.getEntry().getKey(), BubbleController.DISMISS_NO_LONGER_BUBBLE);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700841 assertFalse(mBubbleController.hasBubbles());
842
Mady Mellorc2ff0112019-03-28 14:18:06 -0700843 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
Evan Laird04373662020-01-24 17:37:39 -0500844 mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700845
Lyn Han2f6e89d2020-04-15 10:01:01 -0700846 // Notif is no longer a bubble, so we should not intercept removal.
Mady Mellorc2ff0112019-03-28 14:18:06 -0700847 assertFalse(intercepted);
848 }
849
Mady Mellorf44b6832020-01-14 13:26:14 -0800850 @Test
Lyn Han2f6e89d2020-04-15 10:01:01 -0700851 public void testOverflowBubble_maxReached_notInShade_bubbleRemoved() {
852 mBubbleController.updateBubble(
853 mRow.getEntry(), /* suppressFlyout */ false, /* showInShade */ false);
854 mBubbleController.updateBubble(
855 mRow2.getEntry(), /* suppressFlyout */ false, /* showInShade */ false);
856 mBubbleController.updateBubble(
857 mRow3.getEntry(), /* suppressFlyout */ false, /* showInShade */ false);
858 assertEquals(mBubbleData.getBubbles().size(), 3);
859
860 mBubbleData.setMaxOverflowBubbles(1);
861 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000862 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700863 assertEquals(mBubbleData.getBubbles().size(), 2);
864 assertEquals(mBubbleData.getOverflowBubbles().size(), 1);
865
866 mBubbleController.removeBubble(
Pinyao Ting3c930612020-05-19 00:26:03 +0000867 mRow2.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700868 // Overflow max of 1 is reached; mRow is oldest, so it gets removed
869 verify(mNotificationEntryManager, times(1)).performRemoveNotification(
870 mRow.getEntry().getSbn(), REASON_CANCEL);
871 assertEquals(mBubbleData.getBubbles().size(), 1);
872 assertEquals(mBubbleData.getOverflowBubbles().size(), 1);
873 }
874
875 @Test
Mady Mellorf44b6832020-01-14 13:26:14 -0800876 public void testNotifyShadeSuppressionChange_notificationDismiss() {
877 BubbleController.NotificationSuppressionChangedListener listener =
878 mock(BubbleController.NotificationSuppressionChangedListener.class);
879 mBubbleData.setSuppressionChangedListener(listener);
880
Mady Mellor78133512020-01-31 08:45:52 -0800881 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorf44b6832020-01-14 13:26:14 -0800882
883 assertTrue(mBubbleController.hasBubbles());
884 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500885 mRow.getEntry()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800886
Evan Laird04373662020-01-24 17:37:39 -0500887 mRemoveInterceptor.onNotificationRemoveRequested(
888 mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL);
Mady Mellorf44b6832020-01-14 13:26:14 -0800889
890 // Should update show in shade state
891 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500892 mRow.getEntry()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800893
894 // Should notify delegate that shade state changed
895 verify(listener).onBubbleNotificationSuppressionChange(
Lyn Han2f6e89d2020-04-15 10:01:01 -0700896 mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800897 }
898
899 @Test
900 public void testNotifyShadeSuppressionChange_bubbleExpanded() {
901 BubbleController.NotificationSuppressionChangedListener listener =
902 mock(BubbleController.NotificationSuppressionChangedListener.class);
903 mBubbleData.setSuppressionChangedListener(listener);
904
Mady Mellor78133512020-01-31 08:45:52 -0800905 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorf44b6832020-01-14 13:26:14 -0800906
907 assertTrue(mBubbleController.hasBubbles());
908 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500909 mRow.getEntry()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800910
911 mBubbleData.setExpanded(true);
912
913 // Once a bubble is expanded the notif is suppressed
914 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
Beverlyed8aea22020-01-22 16:52:47 -0500915 mRow.getEntry()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800916
917 // Should notify delegate that shade state changed
918 verify(listener).onBubbleNotificationSuppressionChange(
Lyn Han2f6e89d2020-04-15 10:01:01 -0700919 mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
Mady Mellorf44b6832020-01-14 13:26:14 -0800920 }
921
Beverlya53fb0d2020-01-29 15:26:13 -0500922 @Test
923 public void testBubbleSummaryDismissal_suppressesSummaryAndBubbleFromShade() throws Exception {
924 // GIVEN a group summary with a bubble child
925 ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0);
926 ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
927 mEntryListener.onPendingEntryAdded(groupedBubble.getEntry());
928 groupSummary.addChildNotification(groupedBubble);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700929 assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
Beverlya53fb0d2020-01-29 15:26:13 -0500930
931 // WHEN the summary is dismissed
932 mBubbleController.handleDismissalInterception(groupSummary.getEntry());
933
934 // THEN the summary and bubbled child are suppressed from the shade
935 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
936 groupedBubble.getEntry()));
937 assertTrue(mBubbleData.isSummarySuppressed(groupSummary.getEntry().getSbn().getGroupKey()));
938 }
939
940 @Test
941 public void testAppRemovesSummary_removesAllBubbleChildren() throws Exception {
942 // GIVEN a group summary with a bubble child
943 ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0);
944 ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
945 mEntryListener.onPendingEntryAdded(groupedBubble.getEntry());
946 groupSummary.addChildNotification(groupedBubble);
Lyn Han2f6e89d2020-04-15 10:01:01 -0700947 assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
Beverlya53fb0d2020-01-29 15:26:13 -0500948
949 // GIVEN the summary is dismissed
950 mBubbleController.handleDismissalInterception(groupSummary.getEntry());
951
952 // WHEN the summary is cancelled by the app
Julia Reynolds138111f2020-02-26 11:17:39 -0500953 mEntryListener.onEntryRemoved(groupSummary.getEntry(), null, false, REASON_APP_CANCEL);
Beverlya53fb0d2020-01-29 15:26:13 -0500954
955 // THEN the summary and its children are removed from bubble data
Lyn Han2f6e89d2020-04-15 10:01:01 -0700956 assertFalse(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
Beverlya53fb0d2020-01-29 15:26:13 -0500957 assertFalse(mBubbleData.isSummarySuppressed(
958 groupSummary.getEntry().getSbn().getGroupKey()));
959 }
960
961 @Test
962 public void testSummaryDismissal_marksBubblesHiddenFromShadeAndDismissesNonBubbledChildren()
963 throws Exception {
964 // GIVEN a group summary with two (non-bubble) children and one bubble child
965 ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(2);
966 ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
967 mEntryListener.onPendingEntryAdded(groupedBubble.getEntry());
968 groupSummary.addChildNotification(groupedBubble);
969
970 // WHEN the summary is dismissed
971 mBubbleController.handleDismissalInterception(groupSummary.getEntry());
972
973 // THEN only the NON-bubble children are dismissed
Kevin Han43077f92020-02-28 12:51:53 -0800974 List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren();
Beverlya53fb0d2020-01-29 15:26:13 -0500975 verify(mNotificationEntryManager, times(1)).performRemoveNotification(
976 childrenRows.get(0).getEntry().getSbn(), REASON_GROUP_SUMMARY_CANCELED);
977 verify(mNotificationEntryManager, times(1)).performRemoveNotification(
978 childrenRows.get(1).getEntry().getSbn(), REASON_GROUP_SUMMARY_CANCELED);
979 verify(mNotificationEntryManager, never()).performRemoveNotification(
980 eq(groupedBubble.getEntry().getSbn()), anyInt());
981
982 // THEN the bubble child is suppressed from the shade
983 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
984 groupedBubble.getEntry()));
985
986 // THEN the summary is removed from GroupManager
987 verify(mNotificationGroupManager, times(1)).onEntryRemoved(groupSummary.getEntry());
988 }
989
Mady Mellore80930e2019-03-21 16:00:45 -0700990 /**
Aran Inkc4381c42020-02-06 13:11:53 -0500991 * Sets the bubble metadata flags for this entry. These ]flags are normally set by
Mady Mellor8d25b202019-06-25 13:59:28 -0700992 * NotificationManagerService when the notification is sent, however, these tests do not
993 * go through that path so we set them explicitly when testing.
994 */
995 private void setMetadataFlags(NotificationEntry entry, int flag, boolean enableFlag) {
996 Notification.BubbleMetadata bubbleMetadata =
Ned Burns00b4b2d2019-10-17 22:09:27 -0400997 entry.getSbn().getNotification().getBubbleMetadata();
Mady Mellor8d25b202019-06-25 13:59:28 -0700998 int flags = bubbleMetadata.getFlags();
999 if (enableFlag) {
1000 flags |= flag;
1001 } else {
1002 flags &= ~flag;
1003 }
1004 bubbleMetadata.setFlags(flags);
1005 }
Mady Mellorebdbbb92018-11-15 14:36:48 -08001006}