blob: 0aa103fa27dafe95ef44a29386705d95c65c3552 [file] [log] [blame]
Selim Cinek2ffa02f2017-03-06 15:56:37 -08001/*
2 * Copyright (C) 2017 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
Rohan Shah20790b82018-07-02 17:21:04 -070017package com.android.systemui.statusbar.notification.row;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080018
Rohan Shah63411fc2018-03-28 19:05:52 -070019import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
Jason Monk6dceace2018-05-15 20:24:07 -040020
Ned Burns1a5e22f2019-02-14 15:11:52 -050021import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_ALL;
22import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_HEADS_UP;
23import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_PUBLIC;
Kevind4660b22018-09-27 10:57:35 -070024
Rohan Shah63411fc2018-03-28 19:05:52 -070025import static org.junit.Assert.assertEquals;
Rohan Shah524cf7b2018-03-15 14:40:02 -070026import static org.junit.Assert.assertFalse;
Kevind4660b22018-09-27 10:57:35 -070027import static org.junit.Assert.assertNull;
Rohan Shah524cf7b2018-03-15 14:40:02 -070028import static org.junit.Assert.assertTrue;
Selim Cinek817abe72017-05-24 11:08:55 -070029import static org.mockito.ArgumentMatchers.any;
Julia Reynoldsb5867452018-02-28 16:31:35 -050030import static org.mockito.ArgumentMatchers.anyInt;
Rohan Shahc6990a02018-03-23 17:24:17 -070031import static org.mockito.ArgumentMatchers.eq;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080032import static org.mockito.Mockito.mock;
Rohan Shahc6990a02018-03-23 17:24:17 -070033import static org.mockito.Mockito.reset;
Lucas Dupinb6ed63b2017-05-30 16:17:42 -070034import static org.mockito.Mockito.spy;
Julia Reynoldsfc640012018-02-21 12:25:27 -050035import static org.mockito.Mockito.times;
Selim Cinek817abe72017-05-24 11:08:55 -070036import static org.mockito.Mockito.verify;
Julia Reynoldsfc640012018-02-21 12:25:27 -050037import static org.mockito.Mockito.when;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080038
Julia Reynoldsfc640012018-02-21 12:25:27 -050039import android.app.AppOpsManager;
Rohan Shah63411fc2018-03-28 19:05:52 -070040import android.app.NotificationChannel;
Jason Monk6dceace2018-05-15 20:24:07 -040041import android.testing.AndroidTestingRunner;
Jason Monka716bac2018-12-05 15:48:21 -050042import android.testing.TestableLooper;
Jason Monk6dceace2018-05-15 20:24:07 -040043import android.testing.TestableLooper.RunWithLooper;
Julia Reynoldsfc640012018-02-21 12:25:27 -050044import android.util.ArraySet;
45import android.view.NotificationHeaderView;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080046import android.view.View;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080047
Brett Chabot84151d92019-02-27 15:37:59 -080048import androidx.test.filters.SmallTest;
49
Jason Monkc429f692017-06-27 13:13:49 -040050import com.android.systemui.SysuiTestCase;
Rohan Shahc6990a02018-03-23 17:24:17 -070051import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
Rohan Shah20790b82018-07-02 17:21:04 -070052import com.android.systemui.statusbar.NotificationTestHelper;
Selim Cinek5cf1d052017-06-01 17:36:46 -070053import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
Rohan Shah20790b82018-07-02 17:21:04 -070054import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
Jason Monkfba8faf2017-05-23 10:42:59 -040055
Selim Cinek2ffa02f2017-03-06 15:56:37 -080056import org.junit.Assert;
57import org.junit.Before;
Rohan Shah524cf7b2018-03-15 14:40:02 -070058import org.junit.Rule;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080059import org.junit.Test;
60import org.junit.runner.RunWith;
Rohan Shah524cf7b2018-03-15 14:40:02 -070061import org.mockito.Mock;
Rohan Shah524cf7b2018-03-15 14:40:02 -070062import org.mockito.junit.MockitoJUnit;
63import org.mockito.junit.MockitoRule;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080064
Rohan Shah63411fc2018-03-28 19:05:52 -070065import java.util.List;
Selim Cinek8875de12018-03-22 10:14:32 -070066
Selim Cinek2ffa02f2017-03-06 15:56:37 -080067@SmallTest
Jason Monk6dceace2018-05-15 20:24:07 -040068@RunWith(AndroidTestingRunner.class)
Jason Monka716bac2018-12-05 15:48:21 -050069@RunWithLooper
Jason Monkfba8faf2017-05-23 10:42:59 -040070public class ExpandableNotificationRowTest extends SysuiTestCase {
Selim Cinek2ffa02f2017-03-06 15:56:37 -080071
Rohan Shah524cf7b2018-03-15 14:40:02 -070072 private ExpandableNotificationRow mGroupRow;
73
Selim Cinek6fd06b52017-03-07 15:54:10 -080074 private NotificationTestHelper mNotificationTestHelper;
Selim Cinek8875de12018-03-22 10:14:32 -070075 boolean mHeadsUpAnimatingAway = false;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080076
Rohan Shah524cf7b2018-03-15 14:40:02 -070077 @Rule public MockitoRule mockito = MockitoJUnit.rule();
78 @Mock private NotificationBlockingHelperManager mBlockingHelperManager;
79
Selim Cinek2ffa02f2017-03-06 15:56:37 -080080 @Before
Selim Cinek2630dc72017-04-20 15:16:10 -070081 public void setUp() throws Exception {
Jason Monka716bac2018-12-05 15:48:21 -050082 com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
Selim Cinek6fd06b52017-03-07 15:54:10 -080083 mNotificationTestHelper = new NotificationTestHelper(mContext);
Rohan Shah524cf7b2018-03-15 14:40:02 -070084 mGroupRow = mNotificationTestHelper.createGroup();
85 mGroupRow.setHeadsUpAnimatingAwayListener(
Selim Cinek8875de12018-03-22 10:14:32 -070086 animatingAway -> mHeadsUpAnimatingAway = animatingAway);
Rohan Shah524cf7b2018-03-15 14:40:02 -070087 mDependency.injectTestDependency(
88 NotificationBlockingHelperManager.class,
89 mBlockingHelperManager);
Selim Cinek2ffa02f2017-03-06 15:56:37 -080090 }
91
92 @Test
93 public void testGroupSummaryNotShowingIconWhenPublic() {
Rohan Shah524cf7b2018-03-15 14:40:02 -070094 mGroupRow.setSensitive(true, true);
95 mGroupRow.setHideSensitiveForIntrinsicHeight(true);
96 assertTrue(mGroupRow.isSummaryWithChildren());
97 assertFalse(mGroupRow.isShowingIcon());
Selim Cinek2ffa02f2017-03-06 15:56:37 -080098 }
99
Selim Cinek1826d982017-03-06 20:47:37 -0800100 @Test
101 public void testNotificationHeaderVisibleWhenAnimating() {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700102 mGroupRow.setSensitive(true, true);
103 mGroupRow.setHideSensitive(true, false, 0, 0);
104 mGroupRow.setHideSensitive(false, true, 0, 0);
105 assertTrue(mGroupRow.getChildrenContainer().getVisibleHeader().getVisibility()
Selim Cinek6fd06b52017-03-07 15:54:10 -0800106 == View.VISIBLE);
Selim Cinek1826d982017-03-06 20:47:37 -0800107 }
108
Selim Cinek817abe72017-05-24 11:08:55 -0700109 @Test
110 public void testUserLockedResetEvenWhenNoChildren() {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700111 mGroupRow.setUserLocked(true);
112 mGroupRow.removeAllChildren();
113 mGroupRow.setUserLocked(false);
114 assertFalse("The childrencontainer should not be userlocked but is, the state "
115 + "seems out of sync.", mGroupRow.getChildrenContainer().isUserLocked());
Selim Cinek817abe72017-05-24 11:08:55 -0700116 }
117
118 @Test
119 public void testReinflatedOnDensityChange() {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700120 mGroupRow.setUserLocked(true);
121 mGroupRow.removeAllChildren();
122 mGroupRow.setUserLocked(false);
Selim Cinek817abe72017-05-24 11:08:55 -0700123 NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700124 mGroupRow.setChildrenContainer(mockContainer);
125 mGroupRow.onDensityOrFontScaleChanged();
Selim Cinek817abe72017-05-24 11:08:55 -0700126 verify(mockContainer).reInflateViews(any(), any());
127 }
128
Lucas Dupinb6ed63b2017-05-30 16:17:42 -0700129 @Test
130 public void testIconColorShouldBeUpdatedWhenSensitive() throws Exception {
Kevin38ce6fa2018-10-17 16:00:14 -0700131 ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow(
132 FLAG_CONTENT_VIEW_ALL));
Lucas Dupinb6ed63b2017-05-30 16:17:42 -0700133 row.setSensitive(true, true);
134 row.setHideSensitive(true, false, 0, 0);
135 verify(row).updateShelfIconColor();
136 }
Selim Cinek5cf1d052017-06-01 17:36:46 -0700137
138 @Test
Selim Cineka7c69632017-06-07 15:51:29 -0700139 public void testIconColorShouldBeUpdatedWhenSettingDark() throws Exception {
140 ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow());
141 row.setDark(true, false, 0);
142 verify(row).updateShelfIconColor();
143 }
Ian Pedowitza27856d2017-06-07 17:47:38 -0700144
145 @Test
Kevind5022f92018-10-08 18:30:26 -0700146 public void testFreeContentViewWhenSafe() throws Exception {
147 ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_CONTENT_VIEW_ALL);
Kevind4660b22018-09-27 10:57:35 -0700148
Kevind5022f92018-10-08 18:30:26 -0700149 row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP);
Kevind4660b22018-09-27 10:57:35 -0700150
151 assertNull(row.getPrivateLayout().getHeadsUpChild());
152 }
153
154 @Test
Kevin38ce6fa2018-10-17 16:00:14 -0700155 public void setNeedsRedactionSetsInflationFlag() throws Exception {
156 ExpandableNotificationRow row = mNotificationTestHelper.createRow();
157
158 row.setNeedsRedaction(true);
159
160 assertTrue(row.getNotificationInflater().isInflationFlagSet(FLAG_CONTENT_VIEW_PUBLIC));
161 }
162
163 @Test
164 public void setNeedsRedactionFreesViewWhenFalse() throws Exception {
165 ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_CONTENT_VIEW_ALL);
166 row.setNeedsRedaction(true);
167 row.getPublicLayout().setVisibility(View.GONE);
168
169 row.setNeedsRedaction(false);
170
171 assertNull(row.getPublicLayout().getContractedChild());
172 }
173
174 @Test
Selim Cinek5cf1d052017-06-01 17:36:46 -0700175 public void testAboveShelfChangedListenerCalled() throws Exception {
176 ExpandableNotificationRow row = mNotificationTestHelper.createRow();
177 AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
178 row.setAboveShelfChangedListener(listener);
179 row.setHeadsUp(true);
180 verify(listener).onAboveShelfStateChanged(true);
181 }
182
183 @Test
184 public void testAboveShelfChangedListenerCalledPinned() throws Exception {
185 ExpandableNotificationRow row = mNotificationTestHelper.createRow();
186 AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
187 row.setAboveShelfChangedListener(listener);
188 row.setPinned(true);
189 verify(listener).onAboveShelfStateChanged(true);
190 }
191
192 @Test
193 public void testAboveShelfChangedListenerCalledHeadsUpGoingAway() throws Exception {
194 ExpandableNotificationRow row = mNotificationTestHelper.createRow();
195 AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
196 row.setAboveShelfChangedListener(listener);
197 row.setHeadsUpAnimatingAway(true);
198 verify(listener).onAboveShelfStateChanged(true);
199 }
200 @Test
201 public void testAboveShelfChangedListenerCalledWhenGoingBelow() throws Exception {
202 ExpandableNotificationRow row = mNotificationTestHelper.createRow();
203 row.setHeadsUp(true);
204 AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
205 row.setAboveShelfChangedListener(listener);
206 row.setAboveShelf(false);
207 verify(listener).onAboveShelfStateChanged(false);
208 }
Lucas Dupincecc7c22017-09-12 16:02:45 -0700209
210 @Test
211 public void testClickSound() throws Exception {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700212 assertTrue("Should play sounds by default.", mGroupRow.isSoundEffectsEnabled());
213 mGroupRow.setDark(true /* dark */, false /* fade */, 0 /* delay */);
214 mGroupRow.setSecureStateProvider(()-> false);
215 assertFalse("Shouldn't play sounds when dark and trusted.",
216 mGroupRow.isSoundEffectsEnabled());
217 mGroupRow.setSecureStateProvider(()-> true);
218 assertTrue("Should always play sounds when not trusted.",
219 mGroupRow.isSoundEffectsEnabled());
Lucas Dupincecc7c22017-09-12 16:02:45 -0700220 }
Julia Reynoldsfc640012018-02-21 12:25:27 -0500221
222 @Test
Rohan Shahc6990a02018-03-23 17:24:17 -0700223 public void testSetDismissed_longPressListenerRemoved() {
224 ExpandableNotificationRow.LongPressListener listener =
225 mock(ExpandableNotificationRow.LongPressListener.class);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700226 mGroupRow.setLongPressListener(listener);
227 mGroupRow.doLongClickCallback(0,0);
228 verify(listener, times(1)).onLongPress(eq(mGroupRow), eq(0), eq(0),
Rohan Shahc6990a02018-03-23 17:24:17 -0700229 any(NotificationMenuRowPlugin.MenuItem.class));
230 reset(listener);
231
Rohan Shah524cf7b2018-03-15 14:40:02 -0700232 mGroupRow.setDismissed(true);
233 mGroupRow.doLongClickCallback(0,0);
234 verify(listener, times(0)).onLongPress(eq(mGroupRow), eq(0), eq(0),
Rohan Shahc6990a02018-03-23 17:24:17 -0700235 any(NotificationMenuRowPlugin.MenuItem.class));
236 }
237
238 @Test
Julia Reynoldsb5867452018-02-28 16:31:35 -0500239 public void testShowAppOps_noHeader() {
Julia Reynoldsfc640012018-02-21 12:25:27 -0500240 // public notification is custom layout - no header
Rohan Shah524cf7b2018-03-15 14:40:02 -0700241 mGroupRow.setSensitive(true, true);
242 mGroupRow.setAppOpsOnClickListener(null);
243 mGroupRow.showAppOpsIcons(null);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500244 }
245
246 @Test
Julia Reynoldsb5867452018-02-28 16:31:35 -0500247 public void testShowAppOpsIcons_header() {
Julia Reynoldsfc640012018-02-21 12:25:27 -0500248 NotificationHeaderView mockHeader = mock(NotificationHeaderView.class);
249
250 NotificationContentView publicLayout = mock(NotificationContentView.class);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700251 mGroupRow.setPublicLayout(publicLayout);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500252 NotificationContentView privateLayout = mock(NotificationContentView.class);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700253 mGroupRow.setPrivateLayout(privateLayout);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500254 NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
255 when(mockContainer.getNotificationChildCount()).thenReturn(1);
256 when(mockContainer.getHeaderView()).thenReturn(mockHeader);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700257 mGroupRow.setChildrenContainer(mockContainer);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500258
259 ArraySet<Integer> ops = new ArraySet<>();
260 ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700261 mGroupRow.showAppOpsIcons(ops);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500262
263 verify(mockHeader, times(1)).showAppOpsIcons(ops);
264 verify(privateLayout, times(1)).showAppOpsIcons(ops);
265 verify(publicLayout, times(1)).showAppOpsIcons(ops);
266
267 }
Julia Reynoldsb5867452018-02-28 16:31:35 -0500268
269 @Test
270 public void testAppOpsOnClick() {
271 ExpandableNotificationRow.OnAppOpsClickListener l = mock(
272 ExpandableNotificationRow.OnAppOpsClickListener.class);
273 View view = mock(View.class);
274
Rohan Shah524cf7b2018-03-15 14:40:02 -0700275 mGroupRow.setAppOpsOnClickListener(l);
Julia Reynoldsb5867452018-02-28 16:31:35 -0500276
Rohan Shah524cf7b2018-03-15 14:40:02 -0700277 mGroupRow.getAppOpsOnClickListener().onClick(view);
Julia Reynoldsb5867452018-02-28 16:31:35 -0500278 verify(l, times(1)).onClick(any(), anyInt(), anyInt(), any());
279 }
Selim Cinek8875de12018-03-22 10:14:32 -0700280
281 @Test
282 public void testHeadsUpAnimatingAwayListener() {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700283 mGroupRow.setHeadsUpAnimatingAway(true);
Selim Cinek8875de12018-03-22 10:14:32 -0700284 Assert.assertEquals(true, mHeadsUpAnimatingAway);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700285 mGroupRow.setHeadsUpAnimatingAway(false);
Selim Cinek8875de12018-03-22 10:14:32 -0700286 Assert.assertEquals(false, mHeadsUpAnimatingAway);
287 }
Rohan Shah524cf7b2018-03-15 14:40:02 -0700288
289 @Test
290 public void testPerformDismissWithBlockingHelper_falseWhenBlockingHelperIsntShown() {
291 when(mBlockingHelperManager.perhapsShowBlockingHelper(
292 eq(mGroupRow), any(NotificationMenuRowPlugin.class))).thenReturn(false);
293
294 assertFalse(
295 mGroupRow.performDismissWithBlockingHelper(false /* fromAccessibility */));
296 }
297
298 @Test
299 public void testPerformDismissWithBlockingHelper_doesntPerformOnGroupSummary() {
300 ExpandableNotificationRow childRow = mGroupRow.getChildrenContainer().getViewAtPosition(0);
301 when(mBlockingHelperManager.perhapsShowBlockingHelper(eq(childRow), any(NotificationMenuRowPlugin.class)))
302 .thenReturn(true);
303
304 assertTrue(
305 childRow.performDismissWithBlockingHelper(false /* fromAccessibility */));
306
307 verify(mBlockingHelperManager, times(1))
308 .perhapsShowBlockingHelper(eq(childRow), any(NotificationMenuRowPlugin.class));
309 verify(mBlockingHelperManager, times(0))
310 .perhapsShowBlockingHelper(eq(mGroupRow), any(NotificationMenuRowPlugin.class));
311 }
312
313 @Test
314 public void testIsBlockingHelperShowing_isCorrectlyUpdated() {
315 mGroupRow.setBlockingHelperShowing(true);
316 assertTrue(mGroupRow.isBlockingHelperShowing());
317
318 mGroupRow.setBlockingHelperShowing(false);
319 assertFalse(mGroupRow.isBlockingHelperShowing());
320 }
Rohan Shah63411fc2018-03-28 19:05:52 -0700321
322 @Test
323 public void testGetNumUniqueChildren_defaultChannel() {
324 assertEquals(1, mGroupRow.getNumUniqueChannels());
325 }
326
327 @Test
328 public void testGetNumUniqueChildren_multiChannel() {
329 List<ExpandableNotificationRow> childRows =
330 mGroupRow.getChildrenContainer().getNotificationChildren();
331 // Give each child a unique channel id/name.
332 int i = 0;
333 for (ExpandableNotificationRow childRow : childRows) {
334 childRow.getEntry().channel =
335 new NotificationChannel("id" + i, "dinnertime" + i, IMPORTANCE_DEFAULT);
336 i++;
337 }
338
339 assertEquals(3, mGroupRow.getNumUniqueChannels());
340 }
shawnlin4fbeac42018-04-30 20:32:40 +0800341
342 @Test
343 public void testIconScrollXAfterTranslationAndReset() throws Exception {
344 mGroupRow.setTranslation(50);
345 assertEquals(50, -mGroupRow.getEntry().expandedIcon.getScrollX());
346
347 mGroupRow.resetTranslation();
348 assertEquals(0, mGroupRow.getEntry().expandedIcon.getScrollX());
349 }
Aaron Heuckroth17ce40e2018-06-19 15:44:40 -0400350
351 @Test
352 public void testIsExpanded_userExpanded() {
353 mGroupRow.setExpandable(true);
354 Assert.assertFalse(mGroupRow.isExpanded());
355 mGroupRow.setUserExpanded(true);
356 Assert.assertTrue(mGroupRow.isExpanded());
357 }
Selim Cinek2ffa02f2017-03-06 15:56:37 -0800358}