blob: ba434d4fd0bde6f487b0e7cc660a014ea066574e [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;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -070077import com.android.systemui.statusbar.policy.ConfigurationController;
Mady Melloraa8fef22019-04-11 13:36:40 -070078import com.android.systemui.statusbar.policy.HeadsUpManager;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -040079import com.android.systemui.statusbar.policy.ZenModeController;
Mady Mellorebdbbb92018-11-15 14:36:48 -080080
81import org.junit.Before;
82import org.junit.Test;
83import org.junit.runner.RunWith;
Ned Burns01e38212019-01-03 16:32:52 -050084import org.mockito.ArgumentCaptor;
85import org.mockito.Captor;
Mady Mellorebdbbb92018-11-15 14:36:48 -080086import org.mockito.Mock;
87import org.mockito.MockitoAnnotations;
88
89@SmallTest
90@RunWith(AndroidTestingRunner.class)
91@TestableLooper.RunWithLooper(setAsMainLooper = true)
92public class BubbleControllerTest extends SysuiTestCase {
93
94 @Mock
Ned Burns01e38212019-01-03 16:32:52 -050095 private NotificationEntryManager mNotificationEntryManager;
96 @Mock
Mady Mellor22f2f072019-04-18 13:26:18 -070097 private NotificationGroupManager mNotificationGroupManager;
98 @Mock
Mady Mellorebdbbb92018-11-15 14:36:48 -080099 private WindowManager mWindowManager;
100 @Mock
101 private IActivityManager mActivityManager;
102 @Mock
103 private DozeParameters mDozeParameters;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -0700104 @Mock
105 private ConfigurationController mConfigurationController;
Joshua Tsujidd4d9f92019-05-13 13:57:38 -0400106 @Mock
107 private ZenModeController mZenModeController;
108 @Mock
109 private ZenModeConfig mZenModeConfig;
Mady Mellor80c25b22019-06-17 14:40:37 -0700110 @Mock
111 private FaceManager mFaceManager;
Mark Renoufc19b4732019-06-26 12:08:33 -0400112 @Mock
113 private NotificationLockscreenUserManager mLockscreenUserManager;
Mady Mellorf474e0d2019-08-01 11:08:40 -0700114 @Mock
Lucas Dupine25c4872019-07-29 13:51:35 -0700115 private SysuiStatusBarStateController mStatusBarStateController;
116 @Mock
117 private KeyguardBypassController mKeyguardBypassController;
Lyn Hanf1c9b8b2019-03-14 16:49:48 -0700118
Mady Mellorebdbbb92018-11-15 14:36:48 -0800119 private FrameLayout mStatusBarView;
Ned Burns01e38212019-01-03 16:32:52 -0500120 @Captor
121 private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
Mady Mellorc2ff0112019-03-28 14:18:06 -0700122 @Captor
123 private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800124
125 private TestableBubbleController mBubbleController;
126 private StatusBarWindowController mStatusBarWindowController;
Ned Burns01e38212019-01-03 16:32:52 -0500127 private NotificationEntryListener mEntryListener;
Mady Mellorc2ff0112019-03-28 14:18:06 -0700128 private NotificationRemoveInterceptor mRemoveInterceptor;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800129
130 private NotificationTestHelper mNotificationTestHelper;
131 private ExpandableNotificationRow mRow;
132 private ExpandableNotificationRow mRow2;
Mady Mellorfc02cc32019-04-01 14:47:55 -0700133 private ExpandableNotificationRow mNonBubbleNotifRow;
Mady Mellorebdbbb92018-11-15 14:36:48 -0800134
Mady Mellorb4991e62019-01-10 15:14:51 -0800135 @Mock
136 private NotificationData mNotificationData;
Mady Melloracb12152019-01-29 15:24:48 -0800137 @Mock
138 private BubbleController.BubbleStateChangeListener mBubbleStateChangeListener;
139 @Mock
140 private BubbleController.BubbleExpandListener mBubbleExpandListener;
Mark Renouf6b2331c2019-03-21 13:40:08 -0400141 @Mock
Mark Renouf08bc42a2019-03-07 13:01:59 -0500142 private PendingIntent mDeleteIntent;
143
Mady Mellorcfd06c12019-02-13 14:32:12 -0800144 private BubbleData mBubbleData;
145
Mady Mellorebdbbb92018-11-15 14:36:48 -0800146 @Before
147 public void setUp() throws Exception {
148 MockitoAnnotations.initMocks(this);
Joshua Tsujib1a796b2019-01-16 15:43:12 -0800149 mStatusBarView = new FrameLayout(mContext);
Ned Burns01e38212019-01-03 16:32:52 -0500150 mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
Mady Mellor80c25b22019-06-17 14:40:37 -0700151 mContext.addMockSystemService(FaceManager.class, mFaceManager);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800152
153 // Bubbles get added to status bar window view
154 mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
Lucas Dupine25c4872019-07-29 13:51:35 -0700155 mActivityManager, mDozeParameters, mStatusBarStateController,
156 mConfigurationController, mKeyguardBypassController);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800157 mStatusBarWindowController.add(mStatusBarView, 120 /* height */);
158
159 // Need notifications for bubbles
160 mNotificationTestHelper = new NotificationTestHelper(mContext);
Mark Renouf08bc42a2019-03-07 13:01:59 -0500161 mRow = mNotificationTestHelper.createBubble(mDeleteIntent);
162 mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent);
Mady Mellorfc02cc32019-04-01 14:47:55 -0700163 mNonBubbleNotifRow = mNotificationTestHelper.createRow();
Mady Mellor3ed46202019-03-26 20:22:35 -0700164
Ned Burns01e38212019-01-03 16:32:52 -0500165 // Return non-null notification data from the NEM
166 when(mNotificationEntryManager.getNotificationData()).thenReturn(mNotificationData);
Mady Mellor22f2f072019-04-18 13:26:18 -0700167 when(mNotificationData.get(mRow.getEntry().key)).thenReturn(mRow.getEntry());
Mady Mellorb4991e62019-01-10 15:14:51 -0800168 when(mNotificationData.getChannel(mRow.getEntry().key)).thenReturn(mRow.getEntry().channel);
Ned Burns01e38212019-01-03 16:32:52 -0500169
Joshua Tsujidd4d9f92019-05-13 13:57:38 -0400170 mZenModeConfig.suppressedVisualEffects = 0;
171 when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
172
Mady Melloraa8fef22019-04-11 13:36:40 -0700173 TestableNotificationInterruptionStateProvider interruptionStateProvider =
Mady Mellorc55b4122019-06-07 18:14:02 -0700174 new TestableNotificationInterruptionStateProvider(mContext,
175 mock(NotificationFilter.class),
176 mock(StatusBarStateController.class));
Mady Melloraa8fef22019-04-11 13:36:40 -0700177 interruptionStateProvider.setUpWithPresenter(
178 mock(NotificationPresenter.class),
179 mock(HeadsUpManager.class),
180 mock(NotificationInterruptionStateProvider.HeadsUpSuppressor.class));
Mark Renouf71a3af62019-04-08 15:02:54 -0400181 mBubbleData = new BubbleData(mContext);
Mady Mellor22f2f072019-04-18 13:26:18 -0700182 mBubbleController = new TestableBubbleController(mContext,
183 mStatusBarWindowController,
184 mBubbleData,
185 mConfigurationController,
186 interruptionStateProvider,
187 mZenModeController,
188 mLockscreenUserManager,
189 mNotificationGroupManager);
Mady Melloracb12152019-01-29 15:24:48 -0800190 mBubbleController.setBubbleStateChangeListener(mBubbleStateChangeListener);
191 mBubbleController.setExpandListener(mBubbleExpandListener);
Ned Burns01e38212019-01-03 16:32:52 -0500192
193 // Get a reference to the BubbleController's entry listener
194 verify(mNotificationEntryManager, atLeastOnce())
195 .addNotificationEntryListener(mEntryListenerCaptor.capture());
196 mEntryListener = mEntryListenerCaptor.getValue();
Mady Mellorc2ff0112019-03-28 14:18:06 -0700197 // And the remove interceptor
198 verify(mNotificationEntryManager, atLeastOnce())
199 .setNotificationRemoveInterceptor(mRemoveInterceptorCaptor.capture());
200 mRemoveInterceptor = mRemoveInterceptorCaptor.getValue();
Mady Mellorebdbbb92018-11-15 14:36:48 -0800201 }
202
203 @Test
Mady Mellorebdbbb92018-11-15 14:36:48 -0800204 public void testAddBubble() {
Mark Renouff97ed462019-04-05 13:46:24 -0400205 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800206 assertTrue(mBubbleController.hasBubbles());
Mady Melloracb12152019-01-29 15:24:48 -0800207
208 verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800209 }
210
211 @Test
212 public void testHasBubbles() {
213 assertFalse(mBubbleController.hasBubbles());
Mark Renouff97ed462019-04-05 13:46:24 -0400214 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800215 assertTrue(mBubbleController.hasBubbles());
216 }
217
218 @Test
219 public void testRemoveBubble() {
Mark Renouff97ed462019-04-05 13:46:24 -0400220 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellored99c272019-06-13 15:58:30 -0700221 assertNotNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
Mady Mellorebdbbb92018-11-15 14:36:48 -0800222 assertTrue(mBubbleController.hasBubbles());
Mark Renouf71a3af62019-04-08 15:02:54 -0400223 verify(mNotificationEntryManager).updateNotifications();
Mady Melloracb12152019-01-29 15:24:48 -0800224 verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
225
Mark Renouf08bc42a2019-03-07 13:01:59 -0500226 mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
Mady Mellor88552b82019-08-05 22:38:59 +0000227 assertFalse(mStatusBarWindowController.getBubblesShowing());
Mady Mellored99c272019-06-13 15:58:30 -0700228 assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
Mark Renouf71a3af62019-04-08 15:02:54 -0400229 verify(mNotificationEntryManager, times(2)).updateNotifications();
Mady Melloracb12152019-01-29 15:24:48 -0800230 verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800231 }
232
233 @Test
Mady Mellorc2ff0112019-03-28 14:18:06 -0700234 public void testRemoveBubble_withDismissedNotif() {
235 mEntryListener.onPendingEntryAdded(mRow.getEntry());
236 mBubbleController.updateBubble(mRow.getEntry());
237
238 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700239 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700240
241 // Make it look like dismissed notif
Mady Mellorce23c462019-06-17 17:30:07 -0700242 mBubbleData.getBubbleWithKey(mRow.getEntry().key).setShowInShadeWhenBubble(false);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700243
244 // Now remove the bubble
245 mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
246
247 // Since the notif is dismissed, once the bubble is removed, performRemoveNotification gets
248 // called to really remove the notif
249 verify(mNotificationEntryManager, times(1)).performRemoveNotification(
Mady Mellor1a4e86f2019-05-03 16:07:23 -0700250 mRow.getEntry().notification, UNDEFINED_DISMISS_REASON);
Mady Mellorc2ff0112019-03-28 14:18:06 -0700251 assertFalse(mBubbleController.hasBubbles());
252 }
253
254 @Test
Mady Mellorebdbbb92018-11-15 14:36:48 -0800255 public void testDismissStack() {
Mark Renouff97ed462019-04-05 13:46:24 -0400256 mBubbleController.updateBubble(mRow.getEntry());
Mark Renouf71a3af62019-04-08 15:02:54 -0400257 verify(mNotificationEntryManager, times(1)).updateNotifications();
Mady Mellored99c272019-06-13 15:58:30 -0700258 assertNotNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
Mark Renouff97ed462019-04-05 13:46:24 -0400259 mBubbleController.updateBubble(mRow2.getEntry());
Mark Renouf71a3af62019-04-08 15:02:54 -0400260 verify(mNotificationEntryManager, times(2)).updateNotifications();
Mady Mellored99c272019-06-13 15:58:30 -0700261 assertNotNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().key));
Mady Mellorebdbbb92018-11-15 14:36:48 -0800262 assertTrue(mBubbleController.hasBubbles());
263
Mark Renouf08bc42a2019-03-07 13:01:59 -0500264 mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE);
Mady Mellor88552b82019-08-05 22:38:59 +0000265 assertFalse(mStatusBarWindowController.getBubblesShowing());
Mark Renouf71a3af62019-04-08 15:02:54 -0400266 verify(mNotificationEntryManager, times(3)).updateNotifications();
Mady Mellored99c272019-06-13 15:58:30 -0700267 assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
268 assertNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().key));
Mady Mellorebdbbb92018-11-15 14:36:48 -0800269 }
270
271 @Test
Mady Melloracb12152019-01-29 15:24:48 -0800272 public void testExpandCollapseStack() {
Mady Mellorebdbbb92018-11-15 14:36:48 -0800273 assertFalse(mBubbleController.isStackExpanded());
Mady Melloracb12152019-01-29 15:24:48 -0800274
275 // Mark it as a bubble and add it explicitly
276 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400277 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800278
Mady Mellorce23c462019-06-17 17:30:07 -0700279 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800280 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700281 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Issei Suzukiac9fcb72019-02-04 17:45:57 +0100282 assertFalse(mStatusBarWindowController.getBubbleExpanded());
Mady Melloracb12152019-01-29 15:24:48 -0800283
284 // Expand the stack
Mady Mellorebdbbb92018-11-15 14:36:48 -0800285 BubbleStackView stackView = mBubbleController.getStackView();
Mark Renouf71a3af62019-04-08 15:02:54 -0400286 mBubbleController.expandStack();
Mady Mellorebdbbb92018-11-15 14:36:48 -0800287 assertTrue(mBubbleController.isStackExpanded());
Mady Melloracb12152019-01-29 15:24:48 -0800288 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
Issei Suzukiac9fcb72019-02-04 17:45:57 +0100289 assertTrue(mStatusBarWindowController.getBubbleExpanded());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800290
Mady Mellorce23c462019-06-17 17:30:07 -0700291 // Make sure the notif is suppressed
292 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Melloracb12152019-01-29 15:24:48 -0800293
294 // Collapse
Mark Renouf71a3af62019-04-08 15:02:54 -0400295 mBubbleController.collapseStack();
Mady Melloracb12152019-01-29 15:24:48 -0800296 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().key);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800297 assertFalse(mBubbleController.isStackExpanded());
Issei Suzukiac9fcb72019-02-04 17:45:57 +0100298 assertFalse(mStatusBarWindowController.getBubbleExpanded());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800299 }
300
301 @Test
Mady Melloracb12152019-01-29 15:24:48 -0800302 public void testCollapseAfterChangingExpandedBubble() {
303 // Mark it as a bubble and add it explicitly
304 mEntryListener.onPendingEntryAdded(mRow.getEntry());
305 mEntryListener.onPendingEntryAdded(mRow2.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400306 mBubbleController.updateBubble(mRow.getEntry());
307 mBubbleController.updateBubble(mRow2.getEntry());
Mady Mellorebdbbb92018-11-15 14:36:48 -0800308
Mady Mellorce23c462019-06-17 17:30:07 -0700309 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800310 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700311 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
312 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
313 mRow2.getEntry().key));
Mady Melloracb12152019-01-29 15:24:48 -0800314
315 // Expand
Mady Mellorebdbbb92018-11-15 14:36:48 -0800316 BubbleStackView stackView = mBubbleController.getStackView();
Mark Renouf71a3af62019-04-08 15:02:54 -0400317 mBubbleController.expandStack();
Mady Mellorebdbbb92018-11-15 14:36:48 -0800318 assertTrue(mBubbleController.isStackExpanded());
Mark Renoufba5ab512019-05-02 15:21:01 -0400319 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().key);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800320
Mark Renoufba5ab512019-05-02 15:21:01 -0400321 // Last added is the one that is expanded
Mark Renouf71a3af62019-04-08 15:02:54 -0400322 assertEquals(mRow2.getEntry(), stackView.getExpandedBubbleView().getEntry());
Mady Mellorce23c462019-06-17 17:30:07 -0700323 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry().key));
Mark Renouf71a3af62019-04-08 15:02:54 -0400324
Mark Renoufba5ab512019-05-02 15:21:01 -0400325 // Switch which bubble is expanded
326 mBubbleController.selectBubble(mRow.getEntry().key);
Mady Mellor99a302602019-06-14 11:39:56 -0700327 stackView.setExpandedBubble(mRow.getEntry().key);
Mark Renoufba5ab512019-05-02 15:21:01 -0400328 assertEquals(mRow.getEntry(), stackView.getExpandedBubbleView().getEntry());
Mady Mellorce23c462019-06-17 17:30:07 -0700329 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mark Renoufba5ab512019-05-02 15:21:01 -0400330
Mady Melloracb12152019-01-29 15:24:48 -0800331 // collapse for previous bubble
Mark Renoufba5ab512019-05-02 15:21:01 -0400332 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().key);
Mady Melloracb12152019-01-29 15:24:48 -0800333 // expand for selected bubble
Mark Renoufba5ab512019-05-02 15:21:01 -0400334 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
Mady Melloredd4ee12019-01-18 10:45:11 -0800335
Mady Melloracb12152019-01-29 15:24:48 -0800336 // Collapse
Mady Mellorebdbbb92018-11-15 14:36:48 -0800337 mBubbleController.collapseStack();
338 assertFalse(mBubbleController.isStackExpanded());
339 }
340
Ned Burns01e38212019-01-03 16:32:52 -0500341 @Test
Mady Melloraea895f02019-07-10 14:37:48 -0700342 public void testExpansionRemovesShowInShadeAndDot() {
Mady Melloracb12152019-01-29 15:24:48 -0800343 // Mark it as a bubble and add it explicitly
344 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400345 mBubbleController.updateBubble(mRow.getEntry());
Mady Melloracb12152019-01-29 15:24:48 -0800346
Mady Mellorce23c462019-06-17 17:30:07 -0700347 // We should have bubbles & their notifs should not be suppressed
Mady Melloracb12152019-01-29 15:24:48 -0800348 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700349 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Melloraea895f02019-07-10 14:37:48 -0700350 assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
Mady Melloracb12152019-01-29 15:24:48 -0800351
352 // Expand
Mark Renouf71a3af62019-04-08 15:02:54 -0400353 mBubbleController.expandStack();
Mady Melloracb12152019-01-29 15:24:48 -0800354 assertTrue(mBubbleController.isStackExpanded());
355 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
356
Mady Mellorce23c462019-06-17 17:30:07 -0700357 // Notif is suppressed after expansion
358 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Melloraea895f02019-07-10 14:37:48 -0700359 // Notif shouldn't show dot after expansion
360 assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
361 }
362
363 @Test
364 public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() {
365 // Mark it as a bubble and add it explicitly
366 mEntryListener.onPendingEntryAdded(mRow.getEntry());
367 mBubbleController.updateBubble(mRow.getEntry());
368
369 // We should have bubbles & their notifs should not be suppressed
370 assertTrue(mBubbleController.hasBubbles());
371 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
372 assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
373
374 // Expand
375 BubbleStackView stackView = mBubbleController.getStackView();
376 mBubbleController.expandStack();
377 assertTrue(mBubbleController.isStackExpanded());
378 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
379
380 // Notif is suppressed after expansion
381 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
382 // Notif shouldn't show dot after expansion
383 assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
384
385 // Send update
386 mEntryListener.onPreEntryUpdated(mRow.getEntry());
387
388 // Nothing should have changed
389 // Notif is suppressed after expansion
390 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
391 // Notif shouldn't show dot after expansion
392 assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
Mady Melloracb12152019-01-29 15:24:48 -0800393 }
394
395 @Test
396 public void testRemoveLastExpandedCollapses() {
397 // Mark it as a bubble and add it explicitly
398 mEntryListener.onPendingEntryAdded(mRow.getEntry());
399 mEntryListener.onPendingEntryAdded(mRow2.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400400 mBubbleController.updateBubble(mRow.getEntry());
401 mBubbleController.updateBubble(mRow2.getEntry());
Mady Melloracb12152019-01-29 15:24:48 -0800402 verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
403
404 // Expand
405 BubbleStackView stackView = mBubbleController.getStackView();
Mark Renouf71a3af62019-04-08 15:02:54 -0400406 mBubbleController.expandStack();
Mady Melloracb12152019-01-29 15:24:48 -0800407
408 assertTrue(mBubbleController.isStackExpanded());
Mark Renoufba5ab512019-05-02 15:21:01 -0400409 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().key);
Mady Melloracb12152019-01-29 15:24:48 -0800410
Mark Renoufba5ab512019-05-02 15:21:01 -0400411 // Last added is the one that is expanded
412 assertEquals(mRow2.getEntry(), stackView.getExpandedBubbleView().getEntry());
Mady Mellorce23c462019-06-17 17:30:07 -0700413 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry().key));
Mady Melloracb12152019-01-29 15:24:48 -0800414
415 // Dismiss currently expanded
Mark Renouf08bc42a2019-03-07 13:01:59 -0500416 mBubbleController.removeBubble(stackView.getExpandedBubbleView().getKey(),
417 BubbleController.DISMISS_USER_GESTURE);
Mark Renoufba5ab512019-05-02 15:21:01 -0400418 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().key);
Mady Melloracb12152019-01-29 15:24:48 -0800419
Mark Renoufba5ab512019-05-02 15:21:01 -0400420 // Make sure first bubble is selected
421 assertEquals(mRow.getEntry(), stackView.getExpandedBubbleView().getEntry());
422 verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
Mady Melloracb12152019-01-29 15:24:48 -0800423
424 // Dismiss that one
Mark Renouf08bc42a2019-03-07 13:01:59 -0500425 mBubbleController.removeBubble(stackView.getExpandedBubbleView().getKey(),
426 BubbleController.DISMISS_USER_GESTURE);
Mady Melloracb12152019-01-29 15:24:48 -0800427
428 // Make sure state changes and collapse happens
Mark Renoufba5ab512019-05-02 15:21:01 -0400429 verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().key);
Mady Melloracb12152019-01-29 15:24:48 -0800430 verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
431 assertFalse(mBubbleController.hasBubbles());
432 }
433
434 @Test
Mady Mellor3ed46202019-03-26 20:22:35 -0700435 public void testAutoExpand_FailsNotForeground() {
Mady Mellore80930e2019-03-21 16:00:45 -0700436 assertFalse(mBubbleController.isStackExpanded());
Mady Mellor8d25b202019-06-25 13:59:28 -0700437 setMetadataFlags(mRow.getEntry(),
438 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, false /* enableFlag */);
Mady Mellore80930e2019-03-21 16:00:45 -0700439
440 // Add the auto expand bubble
Mady Mellor8d25b202019-06-25 13:59:28 -0700441 mEntryListener.onPendingEntryAdded(mRow.getEntry());
442 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellore80930e2019-03-21 16:00:45 -0700443
444 // Expansion shouldn't change
445 verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */,
Mady Mellor8d25b202019-06-25 13:59:28 -0700446 mRow.getEntry().key);
Mady Mellore80930e2019-03-21 16:00:45 -0700447 assertFalse(mBubbleController.isStackExpanded());
448
449 // # of bubbles should change
450 verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
451 }
452
453 @Test
Mady Mellor3ed46202019-03-26 20:22:35 -0700454 public void testAutoExpand_SucceedsForeground() {
Mady Mellor8d25b202019-06-25 13:59:28 -0700455 setMetadataFlags(mRow.getEntry(),
456 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */);
Mady Mellore80930e2019-03-21 16:00:45 -0700457
458 // Add the auto expand bubble
Mady Mellor8d25b202019-06-25 13:59:28 -0700459 mEntryListener.onPendingEntryAdded(mRow.getEntry());
460 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellore80930e2019-03-21 16:00:45 -0700461
462 // Expansion should change
463 verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */,
Mady Mellor8d25b202019-06-25 13:59:28 -0700464 mRow.getEntry().key);
Mady Mellore80930e2019-03-21 16:00:45 -0700465 assertTrue(mBubbleController.isStackExpanded());
466
467 // # of bubbles should change
468 verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
Mady Mellore80930e2019-03-21 16:00:45 -0700469 }
470
Mady Mellor3ed46202019-03-26 20:22:35 -0700471 @Test
472 public void testSuppressNotif_FailsNotForeground() {
Mady Mellor8d25b202019-06-25 13:59:28 -0700473 setMetadataFlags(mRow.getEntry(),
474 Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, false /* enableFlag */);
475
Mady Mellor3ed46202019-03-26 20:22:35 -0700476 // Add the suppress notif bubble
Mady Mellor8d25b202019-06-25 13:59:28 -0700477 mEntryListener.onPendingEntryAdded(mRow.getEntry());
478 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellor3ed46202019-03-26 20:22:35 -0700479
Mady Mellorce23c462019-06-17 17:30:07 -0700480 // Should not be suppressed because we weren't forground
481 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellor3ed46202019-03-26 20:22:35 -0700482 // # of bubbles should change
483 verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
484 }
485
486 @Test
487 public void testSuppressNotif_SucceedsForeground() {
Mady Mellor8d25b202019-06-25 13:59:28 -0700488 setMetadataFlags(mRow.getEntry(),
489 Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */);
Mady Mellor3ed46202019-03-26 20:22:35 -0700490
491 // Add the suppress notif bubble
Mady Mellor8d25b202019-06-25 13:59:28 -0700492 mEntryListener.onPendingEntryAdded(mRow.getEntry());
493 mBubbleController.updateBubble(mRow.getEntry());
Mady Mellor3ed46202019-03-26 20:22:35 -0700494
Mady Mellorce23c462019-06-17 17:30:07 -0700495 // Notif should be suppressed because we were foreground
496 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellor3ed46202019-03-26 20:22:35 -0700497
498 // # of bubbles should change
499 verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
Mady Mellor3ed46202019-03-26 20:22:35 -0700500 }
Mady Mellore80930e2019-03-21 16:00:45 -0700501
502 @Test
Mark Renouffec45da2019-03-13 13:24:27 -0400503 public void testExpandStackAndSelectBubble_removedFirst() {
504 final String key = mRow.getEntry().key;
505
506 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mark Renouff97ed462019-04-05 13:46:24 -0400507 mBubbleController.updateBubble(mRow.getEntry());
Mark Renouffec45da2019-03-13 13:24:27 -0400508
Mark Renouffec45da2019-03-13 13:24:27 -0400509 // Simulate notification cancellation.
Mady Mellorc2ff0112019-03-28 14:18:06 -0700510 mRemoveInterceptor.onNotificationRemoveRequested(mRow.getEntry().key, REASON_APP_CANCEL);
Mark Renouffec45da2019-03-13 13:24:27 -0400511
512 mBubbleController.expandStackAndSelectBubble(key);
513 }
514
515 @Test
Mady Mellor3f2efdb2018-11-21 11:30:45 -0800516 public void testMarkNewNotificationAsShowInShade() {
517 mEntryListener.onPendingEntryAdded(mRow.getEntry());
Mady Mellorce23c462019-06-17 17:30:07 -0700518 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Melloraea895f02019-07-10 14:37:48 -0700519 assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
Mady Mellor3f2efdb2018-11-21 11:30:45 -0800520 }
521
Mark Renouf08bc42a2019-03-07 13:01:59 -0500522 @Test
Mady Mellorfc02cc32019-04-01 14:47:55 -0700523 public void testAddNotif_notBubble() {
524 mEntryListener.onPendingEntryAdded(mNonBubbleNotifRow.getEntry());
525 mEntryListener.onPreEntryUpdated(mNonBubbleNotifRow.getEntry());
526
527 verify(mBubbleStateChangeListener, never()).onHasBubblesChanged(anyBoolean());
528 assertThat(mBubbleController.hasBubbles()).isFalse();
529 }
530
531 @Test
Mark Renouf08bc42a2019-03-07 13:01:59 -0500532 public void testDeleteIntent_removeBubble_aged() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400533 mBubbleController.updateBubble(mRow.getEntry());
Mark Renouf08bc42a2019-03-07 13:01:59 -0500534 mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_AGED);
535 verify(mDeleteIntent, never()).send();
536 }
537
538 @Test
539 public void testDeleteIntent_removeBubble_user() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400540 mBubbleController.updateBubble(mRow.getEntry());
Mark Renouf08bc42a2019-03-07 13:01:59 -0500541 mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
542 verify(mDeleteIntent, times(1)).send();
543 }
544
545 @Test
546 public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException {
Mark Renouff97ed462019-04-05 13:46:24 -0400547 mBubbleController.updateBubble(mRow.getEntry());
548 mBubbleController.updateBubble(mRow2.getEntry());
Mark Renouf08bc42a2019-03-07 13:01:59 -0500549 mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE);
550 verify(mDeleteIntent, times(2)).send();
551 }
552
Mady Melloraa8fef22019-04-11 13:36:40 -0700553 @Test
554 public void testRemoveBubble_noLongerBubbleAfterUpdate()
555 throws PendingIntent.CanceledException {
556 mBubbleController.updateBubble(mRow.getEntry());
557 assertTrue(mBubbleController.hasBubbles());
558
559 mRow.getEntry().notification.getNotification().flags &= ~FLAG_BUBBLE;
560 mEntryListener.onPreEntryUpdated(mRow.getEntry());
561
562 assertFalse(mBubbleController.hasBubbles());
563 verify(mDeleteIntent, never()).send();
564 }
565
Mady Mellorc2ff0112019-03-28 14:18:06 -0700566 @Test
567 public void testRemoveBubble_succeeds_appCancel() {
568 mEntryListener.onPendingEntryAdded(mRow.getEntry());
569 mBubbleController.updateBubble(mRow.getEntry());
570
571 assertTrue(mBubbleController.hasBubbles());
572
573 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
574 mRow.getEntry().key, REASON_APP_CANCEL);
575
576 // Cancels always remove so no need to intercept
577 assertFalse(intercepted);
578 assertFalse(mBubbleController.hasBubbles());
579 }
580
581 @Test
582 public void removeBubble_fails_clearAll() {
583 mEntryListener.onPendingEntryAdded(mRow.getEntry());
584 mBubbleController.updateBubble(mRow.getEntry());
585
586 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700587 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700588
589 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
590 mRow.getEntry().key, REASON_CANCEL_ALL);
591
592 // Intercept!
593 assertTrue(intercepted);
594 // Should update show in shade state
Mady Mellorce23c462019-06-17 17:30:07 -0700595 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700596
597 verify(mNotificationEntryManager, never()).performRemoveNotification(
598 any(), anyInt());
599 assertTrue(mBubbleController.hasBubbles());
600 }
601
602 @Test
603 public void removeBubble_fails_userDismissNotif() {
604 mEntryListener.onPendingEntryAdded(mRow.getEntry());
605 mBubbleController.updateBubble(mRow.getEntry());
606
607 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700608 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700609
610 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
611 mRow.getEntry().key, REASON_CANCEL);
612
613 // Intercept!
614 assertTrue(intercepted);
615 // Should update show in shade state
Mady Mellorce23c462019-06-17 17:30:07 -0700616 assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700617
618 verify(mNotificationEntryManager, never()).performRemoveNotification(
619 any(), anyInt());
620 assertTrue(mBubbleController.hasBubbles());
621 }
622
623 @Test
624 public void removeBubble_succeeds_userDismissBubble_userDimissNotif() {
625 mEntryListener.onPendingEntryAdded(mRow.getEntry());
626 mBubbleController.updateBubble(mRow.getEntry());
627
628 assertTrue(mBubbleController.hasBubbles());
Mady Mellorce23c462019-06-17 17:30:07 -0700629 assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
Mady Mellorc2ff0112019-03-28 14:18:06 -0700630
631 // Dismiss the bubble
632 mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
633 assertFalse(mBubbleController.hasBubbles());
634
635 // Dismiss the notification
636 boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
637 mRow.getEntry().key, REASON_CANCEL);
638
639 // It's no longer a bubble so we shouldn't intercept
640 assertFalse(intercepted);
641 }
642
Mady Mellorebdbbb92018-11-15 14:36:48 -0800643 static class TestableBubbleController extends BubbleController {
Issei Suzukic0387542019-03-08 17:31:14 +0100644 // Let's assume surfaces can be synchronized immediately.
Mady Mellorebdbbb92018-11-15 14:36:48 -0800645 TestableBubbleController(Context context,
Lyn Hanf1c9b8b2019-03-14 16:49:48 -0700646 StatusBarWindowController statusBarWindowController, BubbleData data,
Mady Melloraa8fef22019-04-11 13:36:40 -0700647 ConfigurationController configurationController,
Joshua Tsujidd4d9f92019-05-13 13:57:38 -0400648 NotificationInterruptionStateProvider interruptionStateProvider,
Mark Renoufc19b4732019-06-26 12:08:33 -0400649 ZenModeController zenModeController,
Mady Mellor22f2f072019-04-18 13:26:18 -0700650 NotificationLockscreenUserManager lockscreenUserManager,
651 NotificationGroupManager groupManager) {
Mady Melloraa8fef22019-04-11 13:36:40 -0700652 super(context, statusBarWindowController, data, Runnable::run,
Mark Renoufc19b4732019-06-26 12:08:33 -0400653 configurationController, interruptionStateProvider, zenModeController,
Mady Mellor22f2f072019-04-18 13:26:18 -0700654 lockscreenUserManager, groupManager);
Mady Mellorebdbbb92018-11-15 14:36:48 -0800655 }
Mady Mellorebdbbb92018-11-15 14:36:48 -0800656 }
Mady Mellore80930e2019-03-21 16:00:45 -0700657
Mady Mellor8d25b202019-06-25 13:59:28 -0700658 static class TestableNotificationInterruptionStateProvider extends
Mady Melloraa8fef22019-04-11 13:36:40 -0700659 NotificationInterruptionStateProvider {
660
Mady Mellor8d25b202019-06-25 13:59:28 -0700661 TestableNotificationInterruptionStateProvider(Context context,
Mady Mellorc55b4122019-06-07 18:14:02 -0700662 NotificationFilter filter, StatusBarStateController controller) {
663 super(context, filter, controller);
Mady Melloraa8fef22019-04-11 13:36:40 -0700664 mUseHeadsUp = true;
665 }
666 }
667
Mady Mellore80930e2019-03-21 16:00:45 -0700668 /**
669 * @return basic {@link android.app.Notification.BubbleMetadata.Builder}
670 */
671 private Notification.BubbleMetadata.Builder getBuilder() {
672 Intent target = new Intent(mContext, BubblesTestActivity.class);
673 PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target, 0);
674 return new Notification.BubbleMetadata.Builder()
675 .setIntent(bubbleIntent)
676 .setIcon(Icon.createWithResource(mContext, R.drawable.android));
677 }
Mady Mellor8d25b202019-06-25 13:59:28 -0700678
679 /**
680 * Sets the bubble metadata flags for this entry. These flags are normally set by
681 * NotificationManagerService when the notification is sent, however, these tests do not
682 * go through that path so we set them explicitly when testing.
683 */
684 private void setMetadataFlags(NotificationEntry entry, int flag, boolean enableFlag) {
685 Notification.BubbleMetadata bubbleMetadata =
686 entry.notification.getNotification().getBubbleMetadata();
687 int flags = bubbleMetadata.getFlags();
688 if (enableFlag) {
689 flags |= flag;
690 } else {
691 flags &= ~flag;
692 }
693 bubbleMetadata.setFlags(flags);
694 }
Mady Mellorebdbbb92018-11-15 14:36:48 -0800695}