blob: 5a4e6c903650d920d4b59f55a293ef71d5b47816 [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;
Mady Mellore80930e2019-03-21 16:00:45 -070023
Mady Mellor1a4e86f2019-05-03 16:07:23 -070024import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
25
Mady Mellorfc02cc32019-04-01 14:47:55 -070026import static com.google.common.truth.Truth.assertThat;
27
Mady Melloredd4ee12019-01-18 10:45:11 -080028import static org.junit.Assert.assertEquals;
Mady Mellorebdbbb92018-11-15 14:36:48 -080029import static org.junit.Assert.assertFalse;
Mady Mellored99c272019-06-13 15:58:30 -070030import static org.junit.Assert.assertNotNull;
31import static org.junit.Assert.assertNull;
Mady Mellorebdbbb92018-11-15 14:36:48 -080032import static org.junit.Assert.assertTrue;
Mady Mellorc2ff0112019-03-28 14:18:06 -070033import static org.mockito.ArgumentMatchers.any;
Mady Mellorfc02cc32019-04-01 14:47:55 -070034import static org.mockito.ArgumentMatchers.anyBoolean;
Mady Mellorc2ff0112019-03-28 14:18:06 -070035import static org.mockito.ArgumentMatchers.anyInt;
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 Mellore80930e2019-03-21 16:00:45 -070044import android.app.Notification;
Mark Renouf08bc42a2019-03-07 13:01:59 -050045import android.app.PendingIntent;
Mady Mellorebdbbb92018-11-15 14:36:48 -080046import android.content.Context;
Mady Mellore80930e2019-03-21 16:00:45 -070047import android.content.Intent;
Mady Mellore80930e2019-03-21 16:00:45 -070048import android.graphics.drawable.Icon;
Mady Mellor80c25b22019-06-17 14:40:37 -070049import android.hardware.face.FaceManager;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -040050import android.service.notification.ZenModeConfig;
Mady Mellorebdbbb92018-11-15 14:36:48 -080051import android.testing.AndroidTestingRunner;
52import android.testing.TestableLooper;
53import android.view.WindowManager;
54import android.widget.FrameLayout;
55
Brett Chabot84151d92019-02-27 15:37:59 -080056import androidx.test.filters.SmallTest;
57
Mady Mellore80930e2019-03-21 16:00:45 -070058import com.android.systemui.R;
Mady Mellorebdbbb92018-11-15 14:36:48 -080059import com.android.systemui.SysuiTestCase;
Mady Mellorc55b4122019-06-07 18:14:02 -070060import com.android.systemui.plugins.statusbar.StatusBarStateController;
Mark Renoufc19b4732019-06-26 12:08:33 -040061import com.android.systemui.statusbar.NotificationLockscreenUserManager;
Mady Melloraa8fef22019-04-11 13:36:40 -070062import com.android.systemui.statusbar.NotificationPresenter;
Mady Mellorc2ff0112019-03-28 14:18:06 -070063import com.android.systemui.statusbar.NotificationRemoveInterceptor;
Mady Mellorebdbbb92018-11-15 14:36:48 -080064import com.android.systemui.statusbar.NotificationTestHelper;
Lucas Dupine25c4872019-07-29 13:51:35 -070065import com.android.systemui.statusbar.SysuiStatusBarStateController;
Ned Burns01e38212019-01-03 16:32:52 -050066import com.android.systemui.statusbar.notification.NotificationEntryListener;
67import com.android.systemui.statusbar.notification.NotificationEntryManager;
Mady Mellorc55b4122019-06-07 18:14:02 -070068import com.android.systemui.statusbar.notification.NotificationFilter;
Mady Melloraa8fef22019-04-11 13:36:40 -070069import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
Ned Burnsf81c4c42019-01-07 14:10:43 -050070import com.android.systemui.statusbar.notification.collection.NotificationData;
Mady Mellor8d25b202019-06-25 13:59:28 -070071import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Mady Mellorebdbbb92018-11-15 14:36:48 -080072import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
73import com.android.systemui.statusbar.phone.DozeParameters;
Mady Mellor22f2f072019-04-18 13:26:18 -070074import com.android.systemui.statusbar.phone.NotificationGroupManager;
Lucas Dupine25c4872019-07-29 13:51:35 -070075import com.android.systemui.statusbar.phone.KeyguardBypassController;
Mady Mellorebdbbb92018-11-15 14:36:48 -080076import com.android.systemui.statusbar.phone.StatusBarWindowController;
Lucas Dupin6edeb182019-09-25 13:39:21 -070077import com.android.systemui.statusbar.policy.BatteryController;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -070078import com.android.systemui.statusbar.policy.ConfigurationController;
Mady Melloraa8fef22019-04-11 13:36:40 -070079import com.android.systemui.statusbar.policy.HeadsUpManager;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -040080import com.android.systemui.statusbar.policy.ZenModeController;
Mady Mellorebdbbb92018-11-15 14:36:48 -080081
82import org.junit.Before;
83import org.junit.Test;
84import org.junit.runner.RunWith;
Ned Burns01e38212019-01-03 16:32:52 -050085import org.mockito.ArgumentCaptor;
86import org.mockito.Captor;
Mady Mellorebdbbb92018-11-15 14:36:48 -080087import org.mockito.Mock;
88import org.mockito.MockitoAnnotations;
89
90@SmallTest
91@RunWith(AndroidTestingRunner.class)
92@TestableLooper.RunWithLooper(setAsMainLooper = true)
93public class BubbleControllerTest extends SysuiTestCase {
94
95 @Mock
Ned Burns01e38212019-01-03 16:32:52 -050096 private NotificationEntryManager mNotificationEntryManager;
97 @Mock
Mady Mellor22f2f072019-04-18 13:26:18 -070098 private NotificationGroupManager mNotificationGroupManager;
99 @Mock
Mady Mellorebdbbb92018-11-15 14:36:48 -0800100 private WindowManager mWindowManager;
101 @Mock
102 private IActivityManager mActivityManager;
103 @Mock
104 private DozeParameters mDozeParameters;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -0700105 @Mock
106 private ConfigurationController mConfigurationController;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -0400107 @Mock
108 private ZenModeController mZenModeController;
109 @Mock
110 private ZenModeConfig mZenModeConfig;
Mady Mellor80c25b22019-06-17 14:40:37 -0700111 @Mock
112 private FaceManager mFaceManager;
Mark Renoufc19b4732019-06-26 12:08:33 -0400113 @Mock
114 private NotificationLockscreenUserManager mLockscreenUserManager;
Mady Mellorf474e0d2019-08-01 11:08:40 -0700115 @Mock
Lucas Dupine25c4872019-07-29 13:51:35 -0700116 private SysuiStatusBarStateController mStatusBarStateController;
117 @Mock
118 private KeyguardBypassController mKeyguardBypassController;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -0700119
Mady Mellorebdbbb92018-11-15 14:36:48 -0800120 private FrameLayout mStatusBarView;
Ned Burns01e38212019-01-03 16:32:52 -0500121 @Captor
122 private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
Mady Mellorc2ff0112019-03-28 14:18:06 -0700123 @Captor
124 private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800125
126 private TestableBubbleController mBubbleController;
127 private StatusBarWindowController mStatusBarWindowController;
Ned Burns01e38212019-01-03 16:32:52 -0500128 private NotificationEntryListener mEntryListener;
Mady Mellorc2ff0112019-03-28 14:18:06 -0700129 private NotificationRemoveInterceptor mRemoveInterceptor;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800130
131 private NotificationTestHelper mNotificationTestHelper;
132 private ExpandableNotificationRow mRow;
133 private ExpandableNotificationRow mRow2;
Mady Mellorfc02cc32019-04-01 14:47:55 -0700134 private ExpandableNotificationRow mNonBubbleNotifRow;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800135
Mady Mellorb4991e62019-01-10 15:14:51 -0800136 @Mock
137 private NotificationData mNotificationData;
Mady Melloracb12152019-01-29 15:24:48 -0800138 @Mock
139 private BubbleController.BubbleStateChangeListener mBubbleStateChangeListener;
140 @Mock
141 private BubbleController.BubbleExpandListener mBubbleExpandListener;
Mark Renouf6b2331c2019-03-21 13:40:08 -0400142 @Mock
Mark Renouf08bc42a2019-03-07 13:01:59 -0500143 private PendingIntent mDeleteIntent;
144
Mady Mellorcfd06c12019-02-13 14:32:12 -0800145 private BubbleData mBubbleData;
146
Mady Mellorebdbbb92018-11-15 14:36:48 -0800147 @Before
148 public void setUp() throws Exception {
149 MockitoAnnotations.initMocks(this);
Joshua Tsujib1a796b2019-01-16 15:43:12 -0800150 mStatusBarView = new FrameLayout(mContext);
Ned Burns01e38212019-01-03 16:32:52 -0500151 mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
Mady Mellor80c25b22019-06-17 14:40:37 -0700152 mContext.addMockSystemService(FaceManager.class, mFaceManager);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800153
154 // Bubbles get added to status bar window view
155 mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
Lucas Dupine25c4872019-07-29 13:51:35 -0700156 mActivityManager, mDozeParameters, mStatusBarStateController,
157 mConfigurationController, mKeyguardBypassController);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800158 mStatusBarWindowController.add(mStatusBarView, 120 /* height */);
159
160 // Need notifications for bubbles
161 mNotificationTestHelper = new NotificationTestHelper(mContext);
Mark Renouf08bc42a2019-03-07 13:01:59 -0500162 mRow = mNotificationTestHelper.createBubble(mDeleteIntent);
163 mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent);
Mady Mellorfc02cc32019-04-01 14:47:55 -0700164 mNonBubbleNotifRow = mNotificationTestHelper.createRow();
Mady Mellor3ed46202019-03-26 20:22:35 -0700165
Ned Burns01e38212019-01-03 16:32:52 -0500166 // Return non-null notification data from the NEM
167 when(mNotificationEntryManager.getNotificationData()).thenReturn(mNotificationData);
Mady Mellor22f2f072019-04-18 13:26:18 -0700168 when(mNotificationData.get(mRow.getEntry().key)).thenReturn(mRow.getEntry());
Mady Mellorb4991e62019-01-10 15:14:51 -0800169 when(mNotificationData.getChannel(mRow.getEntry().key)).thenReturn(mRow.getEntry().channel);
Ned Burns01e38212019-01-03 16:32:52 -0500170
Joshua Tsujidd4d9f92019-05-13 13:57:38 -0400171 mZenModeConfig.suppressedVisualEffects = 0;
172 when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
173
Mady Melloraa8fef22019-04-11 13:36:40 -0700174 TestableNotificationInterruptionStateProvider interruptionStateProvider =
Mady Mellorc55b4122019-06-07 18:14:02 -0700175 new TestableNotificationInterruptionStateProvider(mContext,
176 mock(NotificationFilter.class),
Lucas Dupin6edeb182019-09-25 13:39:21 -0700177 mock(StatusBarStateController.class),
178 mock(BatteryController.class));
Mady Melloraa8fef22019-04-11 13:36:40 -0700179 interruptionStateProvider.setUpWithPresenter(
180 mock(NotificationPresenter.class),
181 mock(HeadsUpManager.class),
182 mock(NotificationInterruptionStateProvider.HeadsUpSuppressor.class));
Mark Renouf71a3af62019-04-08 15:02:54 -0400183 mBubbleData = new BubbleData(mContext);
Mady Mellor22f2f072019-04-18 13:26:18 -0700184 mBubbleController = new TestableBubbleController(mContext,
185 mStatusBarWindowController,
186 mBubbleData,
187 mConfigurationController,
188 interruptionStateProvider,
189 mZenModeController,
190 mLockscreenUserManager,
191 mNotificationGroupManager);
Mady Melloracb12152019-01-29 15:24:48 -0800192 mBubbleController.setBubbleStateChangeListener(mBubbleStateChangeListener);
193 mBubbleController.setExpandListener(mBubbleExpandListener);
Ned Burns01e38212019-01-03 16:32:52 -0500194
195 // Get a reference to the BubbleController's entry listener
196 verify(mNotificationEntryManager, atLeastOnce())
197 .addNotificationEntryListener(mEntryListenerCaptor.capture());
198 mEntryListener = mEntryListenerCaptor.getValue();
Mady Mellorc2ff0112019-03-28 14:18:06 -0700199 // And the remove interceptor
200 verify(mNotificationEntryManager, atLeastOnce())
201 .setNotificationRemoveInterceptor(mRemoveInterceptorCaptor.capture());
202 mRemoveInterceptor = mRemoveInterceptorCaptor.getValue();
Mady Mellorebdbbb92018-11-15 14:36:48 -0800203 }
204
205 @Test
Mady Mellorebdbbb92018-11-15 14:36:48 -0800206 public void testAddBubble() {
Mark Renouff97ed462019-04-05 13:46:24 -0400207 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800208 assertTrue(mBubbleController.hasBubbles());
Mady Melloracb12152019-01-29 15:24:48 -0800209
210 verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800211 }
212
213 @Test
214 public void testHasBubbles() {
215 assertFalse(mBubbleController.hasBubbles());
Mark Renouff97ed462019-04-05 13:46:24 -0400216 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800217 assertTrue(mBubbleController.hasBubbles());
218 }
219
220 @Test
221 public void testRemoveBubble() {
Mark Renouff97ed462019-04-05 13:46:24 -0400222 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellored99c272019-06-13 15:58:30 -0700223 assertNotNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
Mady Mellorebdbbb92018-11-15 14:36:48 -0800224 assertTrue(mBubbleController.hasBubbles());
Mark Renouf71a3af62019-04-08 15:02:54 -0400225 verify(mNotificationEntryManager).updateNotifications();
Mady Melloracb12152019-01-29 15:24:48 -0800226 verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
227
Mark Renouf08bc42a2019-03-07 13:01:59 -0500228 mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
Mady Mellor88552b82019-08-05 22:38:59 +0000229 assertFalse(mStatusBarWindowController.getBubblesShowing());
Mady Mellored99c272019-06-13 15:58:30 -0700230 assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
Mark Renouf71a3af62019-04-08 15:02:54 -0400231 verify(mNotificationEntryManager, times(2)).updateNotifications();
Mady Melloracb12152019-01-29 15:24:48 -0800232 verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800233 }
234
235 @Test
Mady Mellorc2ff0112019-03-28 14:18:06 -0700236 public void testRemoveBubble_withDismissedNotif() {
237 mEntryListener.onPendingEntryAdded(mRow.getEntry());
238 mBubbleController.updateBubble(mRow.getEntry());
239
240 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700241 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700242
243 // Make it look like dismissed notif
Mady Mellorce23c462019-06-17 17:30:07 -0700244 mBubbleData.getBubbleWithKey(mRow.getEntry().key).setShowInShadeWhenBubble(false);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700245
246 // Now remove the bubble
247 mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
248
249 // Since the notif is dismissed, once the bubble is removed, performRemoveNotification gets
250 // called to really remove the notif
251 verify(mNotificationEntryManager, times(1)).performRemoveNotification(
Mady Mellor1a4e86f2019-05-03 16:07:23 -0700252 mRow.getEntry().notification, UNDEFINED_DISMISS_REASON);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700253 assertFalse(mBubbleController.hasBubbles());
254 }
255
256 @Test
Mady Mellorebdbbb92018-11-15 14:36:48 -0800257 public void testDismissStack() {
Mark Renouff97ed462019-04-05 13:46:24 -0400258 mBubbleController.updateBubble(mRow.getEntry());
Mark Renouf71a3af62019-04-08 15:02:54 -0400259 verify(mNotificationEntryManager, times(1)).updateNotifications();
Mady Mellored99c272019-06-13 15:58:30 -0700260 assertNotNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
Mark Renouff97ed462019-04-05 13:46:24 -0400261 mBubbleController.updateBubble(mRow2.getEntry());
Mark Renouf71a3af62019-04-08 15:02:54 -0400262 verify(mNotificationEntryManager, times(2)).updateNotifications();
Mady Mellored99c272019-06-13 15:58:30 -0700263 assertNotNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().key));
Mady Mellorebdbbb92018-11-15 14:36:48 -0800264 assertTrue(mBubbleController.hasBubbles());
265
Mark Renouf08bc42a2019-03-07 13:01:59 -0500266 mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE);
Mady Mellor88552b82019-08-05 22:38:59 +0000267 assertFalse(mStatusBarWindowController.getBubblesShowing());
Mark Renouf71a3af62019-04-08 15:02:54 -0400268 verify(mNotificationEntryManager, times(3)).updateNotifications();
Mady Mellored99c272019-06-13 15:58:30 -0700269 assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
270 assertNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().key));
Mady Mellorebdbbb92018-11-15 14:36:48 -0800271 }
272
273 @Test
Mady Melloracb12152019-01-29 15:24:48 -0800274 public void testExpandCollapseStack() {
Mady Mellorebdbbb92018-11-15 14:36:48 -0800275 assertFalse(mBubbleController.isStackExpanded());
Mady Melloracb12152019-01-29 15:24:48 -0800276
277 // Mark it as a bubble and add it explicitly
278 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400279 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800280
Mady Mellorce23c462019-06-17 17:30:07 -0700281 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800282 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700283 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Issei Suzukiac9fcb72019-02-04 17:45:57 +0100284 assertFalse(mStatusBarWindowController.getBubbleExpanded());
Mady Melloracb12152019-01-29 15:24:48 -0800285
286 // Expand the stack
Mady Mellorebdbbb92018-11-15 14:36:48 -0800287 BubbleStackView stackView = mBubbleController.getStackView();
Mark Renouf71a3af62019-04-08 15:02:54 -0400288 mBubbleController.expandStack();
Mady Mellorebdbbb92018-11-15 14:36:48 -0800289 assertTrue(mBubbleController.isStackExpanded());
Mady Melloracb12152019-01-29 15:24:48 -0800290 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
Issei Suzukiac9fcb72019-02-04 17:45:57 +0100291 assertTrue(mStatusBarWindowController.getBubbleExpanded());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800292
Mady Mellorce23c462019-06-17 17:30:07 -0700293 // Make sure the notif is suppressed
294 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Melloracb12152019-01-29 15:24:48 -0800295
296 // Collapse
Mark Renouf71a3af62019-04-08 15:02:54 -0400297 mBubbleController.collapseStack();
Mady Melloracb12152019-01-29 15:24:48 -0800298 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().key);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800299 assertFalse(mBubbleController.isStackExpanded());
Issei Suzukiac9fcb72019-02-04 17:45:57 +0100300 assertFalse(mStatusBarWindowController.getBubbleExpanded());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800301 }
302
303 @Test
Mady Melloracb12152019-01-29 15:24:48 -0800304 public void testCollapseAfterChangingExpandedBubble() {
305 // Mark it as a bubble and add it explicitly
306 mEntryListener.onPendingEntryAdded(mRow.getEntry());
307 mEntryListener.onPendingEntryAdded(mRow2.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400308 mBubbleController.updateBubble(mRow.getEntry());
309 mBubbleController.updateBubble(mRow2.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800310
Mady Mellorce23c462019-06-17 17:30:07 -0700311 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800312 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700313 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
314 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
315 mRow2.getEntry().key));
Mady Melloracb12152019-01-29 15:24:48 -0800316
317 // Expand
Mady Mellorebdbbb92018-11-15 14:36:48 -0800318 BubbleStackView stackView = mBubbleController.getStackView();
Mark Renouf71a3af62019-04-08 15:02:54 -0400319 mBubbleController.expandStack();
Mady Mellorebdbbb92018-11-15 14:36:48 -0800320 assertTrue(mBubbleController.isStackExpanded());
Mark Renoufba5ab512019-05-02 15:21:01 -0400321 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().key);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800322
Mark Renoufba5ab512019-05-02 15:21:01 -0400323 // Last added is the one that is expanded
Mark Renouf71a3af62019-04-08 15:02:54 -0400324 assertEquals(mRow2.getEntry(), stackView.getExpandedBubbleView().getEntry());
Mady Mellorce23c462019-06-17 17:30:07 -0700325 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry().key));
Mark Renouf71a3af62019-04-08 15:02:54 -0400326
Mark Renoufba5ab512019-05-02 15:21:01 -0400327 // Switch which bubble is expanded
328 mBubbleController.selectBubble(mRow.getEntry().key);
Mady Mellor99a302602019-06-14 11:39:56 -0700329 stackView.setExpandedBubble(mRow.getEntry().key);
Mark Renoufba5ab512019-05-02 15:21:01 -0400330 assertEquals(mRow.getEntry(), stackView.getExpandedBubbleView().getEntry());
Mady Mellorce23c462019-06-17 17:30:07 -0700331 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mark Renoufba5ab512019-05-02 15:21:01 -0400332
Mady Melloracb12152019-01-29 15:24:48 -0800333 // collapse for previous bubble
Mark Renoufba5ab512019-05-02 15:21:01 -0400334 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().key);
Mady Melloracb12152019-01-29 15:24:48 -0800335 // expand for selected bubble
Mark Renoufba5ab512019-05-02 15:21:01 -0400336 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
Mady Melloredd4ee12019-01-18 10:45:11 -0800337
Mady Melloracb12152019-01-29 15:24:48 -0800338 // Collapse
Mady Mellorebdbbb92018-11-15 14:36:48 -0800339 mBubbleController.collapseStack();
340 assertFalse(mBubbleController.isStackExpanded());
341 }
342
Ned Burns01e38212019-01-03 16:32:52 -0500343 @Test
Mady Melloraea895f02019-07-10 14:37:48 -0700344 public void testExpansionRemovesShowInShadeAndDot() {
Mady Melloracb12152019-01-29 15:24:48 -0800345 // Mark it as a bubble and add it explicitly
346 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400347 mBubbleController.updateBubble(mRow.getEntry());
Mady Melloracb12152019-01-29 15:24:48 -0800348
Mady Mellorce23c462019-06-17 17:30:07 -0700349 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800350 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700351 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Melloraea895f02019-07-10 14:37:48 -0700352 assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
Mady Melloracb12152019-01-29 15:24:48 -0800353
354 // Expand
Mark Renouf71a3af62019-04-08 15:02:54 -0400355 mBubbleController.expandStack();
Mady Melloracb12152019-01-29 15:24:48 -0800356 assertTrue(mBubbleController.isStackExpanded());
357 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
358
Mady Mellorce23c462019-06-17 17:30:07 -0700359 // Notif is suppressed after expansion
360 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Melloraea895f02019-07-10 14:37:48 -0700361 // Notif shouldn't show dot after expansion
362 assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
363 }
364
365 @Test
366 public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() {
367 // Mark it as a bubble and add it explicitly
368 mEntryListener.onPendingEntryAdded(mRow.getEntry());
369 mBubbleController.updateBubble(mRow.getEntry());
370
371 // We should have bubbles & their notifs should not be suppressed
372 assertTrue(mBubbleController.hasBubbles());
373 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
374 assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
375
376 // Expand
377 BubbleStackView stackView = mBubbleController.getStackView();
378 mBubbleController.expandStack();
379 assertTrue(mBubbleController.isStackExpanded());
380 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
381
382 // Notif is suppressed after expansion
383 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
384 // Notif shouldn't show dot after expansion
385 assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
386
387 // Send update
388 mEntryListener.onPreEntryUpdated(mRow.getEntry());
389
390 // Nothing should have changed
391 // Notif is suppressed after expansion
392 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
393 // Notif shouldn't show dot after expansion
394 assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
Mady Melloracb12152019-01-29 15:24:48 -0800395 }
396
397 @Test
398 public void testRemoveLastExpandedCollapses() {
399 // Mark it as a bubble and add it explicitly
400 mEntryListener.onPendingEntryAdded(mRow.getEntry());
401 mEntryListener.onPendingEntryAdded(mRow2.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400402 mBubbleController.updateBubble(mRow.getEntry());
403 mBubbleController.updateBubble(mRow2.getEntry());
Mady Melloracb12152019-01-29 15:24:48 -0800404 verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
405
406 // Expand
407 BubbleStackView stackView = mBubbleController.getStackView();
Mark Renouf71a3af62019-04-08 15:02:54 -0400408 mBubbleController.expandStack();
Mady Melloracb12152019-01-29 15:24:48 -0800409
410 assertTrue(mBubbleController.isStackExpanded());
Mark Renoufba5ab512019-05-02 15:21:01 -0400411 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().key);
Mady Melloracb12152019-01-29 15:24:48 -0800412
Mark Renoufba5ab512019-05-02 15:21:01 -0400413 // Last added is the one that is expanded
414 assertEquals(mRow2.getEntry(), stackView.getExpandedBubbleView().getEntry());
Mady Mellorce23c462019-06-17 17:30:07 -0700415 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry().key));
Mady Melloracb12152019-01-29 15:24:48 -0800416
417 // Dismiss currently expanded
Mark Renouf08bc42a2019-03-07 13:01:59 -0500418 mBubbleController.removeBubble(stackView.getExpandedBubbleView().getKey(),
419 BubbleController.DISMISS_USER_GESTURE);
Mark Renoufba5ab512019-05-02 15:21:01 -0400420 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().key);
Mady Melloracb12152019-01-29 15:24:48 -0800421
Mark Renoufba5ab512019-05-02 15:21:01 -0400422 // Make sure first bubble is selected
423 assertEquals(mRow.getEntry(), stackView.getExpandedBubbleView().getEntry());
424 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
Mady Melloracb12152019-01-29 15:24:48 -0800425
426 // Dismiss that one
Mark Renouf08bc42a2019-03-07 13:01:59 -0500427 mBubbleController.removeBubble(stackView.getExpandedBubbleView().getKey(),
428 BubbleController.DISMISS_USER_GESTURE);
Mady Melloracb12152019-01-29 15:24:48 -0800429
430 // Make sure state changes and collapse happens
Mark Renoufba5ab512019-05-02 15:21:01 -0400431 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().key);
Mady Melloracb12152019-01-29 15:24:48 -0800432 verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
433 assertFalse(mBubbleController.hasBubbles());
434 }
435
436 @Test
Mady Mellor3ed46202019-03-26 20:22:35 -0700437 public void testAutoExpand_FailsNotForeground() {
Mady Mellore80930e2019-03-21 16:00:45 -0700438 assertFalse(mBubbleController.isStackExpanded());
Mady Mellor8d25b202019-06-25 13:59:28 -0700439 setMetadataFlags(mRow.getEntry(),
440 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, false /* enableFlag */);
Mady Mellore80930e2019-03-21 16:00:45 -0700441
442 // Add the auto expand bubble
Mady Mellor8d25b202019-06-25 13:59:28 -0700443 mEntryListener.onPendingEntryAdded(mRow.getEntry());
444 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellore80930e2019-03-21 16:00:45 -0700445
446 // Expansion shouldn't change
447 verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */,
Mady Mellor8d25b202019-06-25 13:59:28 -0700448 mRow.getEntry().key);
Mady Mellore80930e2019-03-21 16:00:45 -0700449 assertFalse(mBubbleController.isStackExpanded());
450
451 // # of bubbles should change
452 verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
453 }
454
455 @Test
Mady Mellor3ed46202019-03-26 20:22:35 -0700456 public void testAutoExpand_SucceedsForeground() {
Mady Mellor8d25b202019-06-25 13:59:28 -0700457 setMetadataFlags(mRow.getEntry(),
458 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */);
Mady Mellore80930e2019-03-21 16:00:45 -0700459
460 // Add the auto expand bubble
Mady Mellor8d25b202019-06-25 13:59:28 -0700461 mEntryListener.onPendingEntryAdded(mRow.getEntry());
462 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellore80930e2019-03-21 16:00:45 -0700463
464 // Expansion should change
465 verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */,
Mady Mellor8d25b202019-06-25 13:59:28 -0700466 mRow.getEntry().key);
Mady Mellore80930e2019-03-21 16:00:45 -0700467 assertTrue(mBubbleController.isStackExpanded());
468
469 // # of bubbles should change
470 verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
Mady Mellore80930e2019-03-21 16:00:45 -0700471 }
472
Mady Mellor3ed46202019-03-26 20:22:35 -0700473 @Test
474 public void testSuppressNotif_FailsNotForeground() {
Mady Mellor8d25b202019-06-25 13:59:28 -0700475 setMetadataFlags(mRow.getEntry(),
476 Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, false /* enableFlag */);
477
Mady Mellor3ed46202019-03-26 20:22:35 -0700478 // Add the suppress notif bubble
Mady Mellor8d25b202019-06-25 13:59:28 -0700479 mEntryListener.onPendingEntryAdded(mRow.getEntry());
480 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellor3ed46202019-03-26 20:22:35 -0700481
Mady Mellorce23c462019-06-17 17:30:07 -0700482 // Should not be suppressed because we weren't forground
483 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellor3ed46202019-03-26 20:22:35 -0700484 // # of bubbles should change
485 verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
486 }
487
488 @Test
489 public void testSuppressNotif_SucceedsForeground() {
Mady Mellor8d25b202019-06-25 13:59:28 -0700490 setMetadataFlags(mRow.getEntry(),
491 Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */);
Mady Mellor3ed46202019-03-26 20:22:35 -0700492
493 // Add the suppress notif bubble
Mady Mellor8d25b202019-06-25 13:59:28 -0700494 mEntryListener.onPendingEntryAdded(mRow.getEntry());
495 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellor3ed46202019-03-26 20:22:35 -0700496
Mady Mellorce23c462019-06-17 17:30:07 -0700497 // Notif should be suppressed because we were foreground
498 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellor3ed46202019-03-26 20:22:35 -0700499
500 // # of bubbles should change
501 verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
Mady Mellor3ed46202019-03-26 20:22:35 -0700502 }
Mady Mellore80930e2019-03-21 16:00:45 -0700503
504 @Test
Mark Renouffec45da2019-03-13 13:24:27 -0400505 public void testExpandStackAndSelectBubble_removedFirst() {
506 final String key = mRow.getEntry().key;
507
508 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400509 mBubbleController.updateBubble(mRow.getEntry());
Mark Renouffec45da2019-03-13 13:24:27 -0400510
Mark Renouffec45da2019-03-13 13:24:27 -0400511 // Simulate notification cancellation.
Mady Mellorc2ff0112019-03-28 14:18:06 -0700512 mRemoveInterceptor.onNotificationRemoveRequested(mRow.getEntry().key, REASON_APP_CANCEL);
Mark Renouffec45da2019-03-13 13:24:27 -0400513
514 mBubbleController.expandStackAndSelectBubble(key);
515 }
516
517 @Test
Mady Mellor3f2efdb2018-11-21 11:30:45 -0800518 public void testMarkNewNotificationAsShowInShade() {
519 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorce23c462019-06-17 17:30:07 -0700520 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Melloraea895f02019-07-10 14:37:48 -0700521 assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
Mady Mellor3f2efdb2018-11-21 11:30:45 -0800522 }
523
Mark Renouf08bc42a2019-03-07 13:01:59 -0500524 @Test
Mady Mellorfc02cc32019-04-01 14:47:55 -0700525 public void testAddNotif_notBubble() {
526 mEntryListener.onPendingEntryAdded(mNonBubbleNotifRow.getEntry());
527 mEntryListener.onPreEntryUpdated(mNonBubbleNotifRow.getEntry());
528
529 verify(mBubbleStateChangeListener, never()).onHasBubblesChanged(anyBoolean());
530 assertThat(mBubbleController.hasBubbles()).isFalse();
531 }
532
533 @Test
Mark Renouf08bc42a2019-03-07 13:01:59 -0500534 public void testDeleteIntent_removeBubble_aged() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400535 mBubbleController.updateBubble(mRow.getEntry());
Mark Renouf08bc42a2019-03-07 13:01:59 -0500536 mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_AGED);
537 verify(mDeleteIntent, never()).send();
538 }
539
540 @Test
541 public void testDeleteIntent_removeBubble_user() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400542 mBubbleController.updateBubble(mRow.getEntry());
Mark Renouf08bc42a2019-03-07 13:01:59 -0500543 mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
544 verify(mDeleteIntent, times(1)).send();
545 }
546
547 @Test
548 public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400549 mBubbleController.updateBubble(mRow.getEntry());
550 mBubbleController.updateBubble(mRow2.getEntry());
Mark Renouf08bc42a2019-03-07 13:01:59 -0500551 mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE);
552 verify(mDeleteIntent, times(2)).send();
553 }
554
Mady Melloraa8fef22019-04-11 13:36:40 -0700555 @Test
556 public void testRemoveBubble_noLongerBubbleAfterUpdate()
557 throws PendingIntent.CanceledException {
558 mBubbleController.updateBubble(mRow.getEntry());
559 assertTrue(mBubbleController.hasBubbles());
560
561 mRow.getEntry().notification.getNotification().flags &= ~FLAG_BUBBLE;
562 mEntryListener.onPreEntryUpdated(mRow.getEntry());
563
564 assertFalse(mBubbleController.hasBubbles());
565 verify(mDeleteIntent, never()).send();
566 }
567
Mady Mellorc2ff0112019-03-28 14:18:06 -0700568 @Test
569 public void testRemoveBubble_succeeds_appCancel() {
570 mEntryListener.onPendingEntryAdded(mRow.getEntry());
571 mBubbleController.updateBubble(mRow.getEntry());
572
573 assertTrue(mBubbleController.hasBubbles());
574
575 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
576 mRow.getEntry().key, REASON_APP_CANCEL);
577
578 // Cancels always remove so no need to intercept
579 assertFalse(intercepted);
580 assertFalse(mBubbleController.hasBubbles());
581 }
582
583 @Test
584 public void removeBubble_fails_clearAll() {
585 mEntryListener.onPendingEntryAdded(mRow.getEntry());
586 mBubbleController.updateBubble(mRow.getEntry());
587
588 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700589 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700590
591 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
592 mRow.getEntry().key, REASON_CANCEL_ALL);
593
594 // Intercept!
595 assertTrue(intercepted);
596 // Should update show in shade state
Mady Mellorce23c462019-06-17 17:30:07 -0700597 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700598
599 verify(mNotificationEntryManager, never()).performRemoveNotification(
600 any(), anyInt());
601 assertTrue(mBubbleController.hasBubbles());
602 }
603
604 @Test
605 public void removeBubble_fails_userDismissNotif() {
606 mEntryListener.onPendingEntryAdded(mRow.getEntry());
607 mBubbleController.updateBubble(mRow.getEntry());
608
609 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700610 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700611
612 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
613 mRow.getEntry().key, REASON_CANCEL);
614
615 // Intercept!
616 assertTrue(intercepted);
617 // Should update show in shade state
Mady Mellorce23c462019-06-17 17:30:07 -0700618 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700619
620 verify(mNotificationEntryManager, never()).performRemoveNotification(
621 any(), anyInt());
622 assertTrue(mBubbleController.hasBubbles());
623 }
624
625 @Test
626 public void removeBubble_succeeds_userDismissBubble_userDimissNotif() {
627 mEntryListener.onPendingEntryAdded(mRow.getEntry());
628 mBubbleController.updateBubble(mRow.getEntry());
629
630 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700631 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700632
633 // Dismiss the bubble
634 mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
635 assertFalse(mBubbleController.hasBubbles());
636
637 // Dismiss the notification
638 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
639 mRow.getEntry().key, REASON_CANCEL);
640
641 // It's no longer a bubble so we shouldn't intercept
642 assertFalse(intercepted);
643 }
644
Mady Mellorebdbbb92018-11-15 14:36:48 -0800645 static class TestableBubbleController extends BubbleController {
Issei Suzukic0387542019-03-08 17:31:14 +0100646 // Let's assume surfaces can be synchronized immediately.
Mady Mellorebdbbb92018-11-15 14:36:48 -0800647 TestableBubbleController(Context context,
Lyn Hanf1c9b8b2019-03-14 16:49:48 -0700648 StatusBarWindowController statusBarWindowController, BubbleData data,
Mady Melloraa8fef22019-04-11 13:36:40 -0700649 ConfigurationController configurationController,
Joshua Tsujidd4d9f92019-05-13 13:57:38 -0400650 NotificationInterruptionStateProvider interruptionStateProvider,
Mark Renoufc19b4732019-06-26 12:08:33 -0400651 ZenModeController zenModeController,
Mady Mellor22f2f072019-04-18 13:26:18 -0700652 NotificationLockscreenUserManager lockscreenUserManager,
653 NotificationGroupManager groupManager) {
Mady Melloraa8fef22019-04-11 13:36:40 -0700654 super(context, statusBarWindowController, data, Runnable::run,
Mark Renoufc19b4732019-06-26 12:08:33 -0400655 configurationController, interruptionStateProvider, zenModeController,
Mady Mellor22f2f072019-04-18 13:26:18 -0700656 lockscreenUserManager, groupManager);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800657 }
Mady Mellorebdbbb92018-11-15 14:36:48 -0800658 }
Mady Mellore80930e2019-03-21 16:00:45 -0700659
Mady Mellor8d25b202019-06-25 13:59:28 -0700660 static class TestableNotificationInterruptionStateProvider extends
Mady Melloraa8fef22019-04-11 13:36:40 -0700661 NotificationInterruptionStateProvider {
662
Mady Mellor8d25b202019-06-25 13:59:28 -0700663 TestableNotificationInterruptionStateProvider(Context context,
Lucas Dupin6edeb182019-09-25 13:39:21 -0700664 NotificationFilter filter, StatusBarStateController controller,
665 BatteryController batteryController) {
666 super(context, filter, controller, batteryController);
Mady Melloraa8fef22019-04-11 13:36:40 -0700667 mUseHeadsUp = true;
668 }
669 }
670
Mady Mellore80930e2019-03-21 16:00:45 -0700671 /**
672 * @return basic {@link android.app.Notification.BubbleMetadata.Builder}
673 */
674 private Notification.BubbleMetadata.Builder getBuilder() {
675 Intent target = new Intent(mContext, BubblesTestActivity.class);
676 PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target, 0);
677 return new Notification.BubbleMetadata.Builder()
678 .setIntent(bubbleIntent)
679 .setIcon(Icon.createWithResource(mContext, R.drawable.android));
680 }
Mady Mellor8d25b202019-06-25 13:59:28 -0700681
682 /**
683 * Sets the bubble metadata flags for this entry. These flags are normally set by
684 * NotificationManagerService when the notification is sent, however, these tests do not
685 * go through that path so we set them explicitly when testing.
686 */
687 private void setMetadataFlags(NotificationEntry entry, int flag, boolean enableFlag) {
688 Notification.BubbleMetadata bubbleMetadata =
689 entry.notification.getNotification().getBubbleMetadata();
690 int flags = bubbleMetadata.getFlags();
691 if (enableFlag) {
692 flags |= flag;
693 } else {
694 flags &= ~flag;
695 }
696 bubbleMetadata.setFlags(flags);
697 }
Mady Mellorebdbbb92018-11-15 14:36:48 -0800698}