blob: f6fb4163bfc48518c6a68f188215271713b7f4ef [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;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080041import android.support.test.filters.SmallTest;
Jason Monk6dceace2018-05-15 20:24:07 -040042import android.testing.AndroidTestingRunner;
Jason Monka716bac2018-12-05 15:48:21 -050043import android.testing.TestableLooper;
Jason Monk6dceace2018-05-15 20:24:07 -040044import android.testing.TestableLooper.RunWithLooper;
Julia Reynoldsfc640012018-02-21 12:25:27 -050045import android.util.ArraySet;
46import android.view.NotificationHeaderView;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080047import android.view.View;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080048
Jason Monkc429f692017-06-27 13:13:49 -040049import com.android.systemui.SysuiTestCase;
Rohan Shahc6990a02018-03-23 17:24:17 -070050import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
Rohan Shah20790b82018-07-02 17:21:04 -070051import com.android.systemui.statusbar.NotificationTestHelper;
Selim Cinek5cf1d052017-06-01 17:36:46 -070052import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
Rohan Shah20790b82018-07-02 17:21:04 -070053import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
Jason Monkfba8faf2017-05-23 10:42:59 -040054
Selim Cinek2ffa02f2017-03-06 15:56:37 -080055import org.junit.Assert;
56import org.junit.Before;
Rohan Shah524cf7b2018-03-15 14:40:02 -070057import org.junit.Rule;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080058import org.junit.Test;
59import org.junit.runner.RunWith;
Rohan Shah524cf7b2018-03-15 14:40:02 -070060import org.mockito.Mock;
Rohan Shah524cf7b2018-03-15 14:40:02 -070061import org.mockito.junit.MockitoJUnit;
62import org.mockito.junit.MockitoRule;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080063
Rohan Shah63411fc2018-03-28 19:05:52 -070064import java.util.List;
Selim Cinek8875de12018-03-22 10:14:32 -070065
Selim Cinek2ffa02f2017-03-06 15:56:37 -080066@SmallTest
Jason Monk6dceace2018-05-15 20:24:07 -040067@RunWith(AndroidTestingRunner.class)
Jason Monka716bac2018-12-05 15:48:21 -050068@RunWithLooper
Jason Monkfba8faf2017-05-23 10:42:59 -040069public class ExpandableNotificationRowTest extends SysuiTestCase {
Selim Cinek2ffa02f2017-03-06 15:56:37 -080070
Rohan Shah524cf7b2018-03-15 14:40:02 -070071 private ExpandableNotificationRow mGroupRow;
72
Selim Cinek6fd06b52017-03-07 15:54:10 -080073 private NotificationTestHelper mNotificationTestHelper;
Selim Cinek8875de12018-03-22 10:14:32 -070074 boolean mHeadsUpAnimatingAway = false;
Selim Cinek2ffa02f2017-03-06 15:56:37 -080075
Rohan Shah524cf7b2018-03-15 14:40:02 -070076 @Rule public MockitoRule mockito = MockitoJUnit.rule();
77 @Mock private NotificationBlockingHelperManager mBlockingHelperManager;
78
Selim Cinek2ffa02f2017-03-06 15:56:37 -080079 @Before
Selim Cinek2630dc72017-04-20 15:16:10 -070080 public void setUp() throws Exception {
Jason Monka716bac2018-12-05 15:48:21 -050081 com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
Selim Cinek6fd06b52017-03-07 15:54:10 -080082 mNotificationTestHelper = new NotificationTestHelper(mContext);
Rohan Shah524cf7b2018-03-15 14:40:02 -070083 mGroupRow = mNotificationTestHelper.createGroup();
84 mGroupRow.setHeadsUpAnimatingAwayListener(
Selim Cinek8875de12018-03-22 10:14:32 -070085 animatingAway -> mHeadsUpAnimatingAway = animatingAway);
Rohan Shah524cf7b2018-03-15 14:40:02 -070086 mDependency.injectTestDependency(
87 NotificationBlockingHelperManager.class,
88 mBlockingHelperManager);
Selim Cinek2ffa02f2017-03-06 15:56:37 -080089 }
90
91 @Test
92 public void testGroupSummaryNotShowingIconWhenPublic() {
Rohan Shah524cf7b2018-03-15 14:40:02 -070093 mGroupRow.setSensitive(true, true);
94 mGroupRow.setHideSensitiveForIntrinsicHeight(true);
95 assertTrue(mGroupRow.isSummaryWithChildren());
96 assertFalse(mGroupRow.isShowingIcon());
Selim Cinek2ffa02f2017-03-06 15:56:37 -080097 }
98
Selim Cinek1826d982017-03-06 20:47:37 -080099 @Test
100 public void testNotificationHeaderVisibleWhenAnimating() {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700101 mGroupRow.setSensitive(true, true);
102 mGroupRow.setHideSensitive(true, false, 0, 0);
103 mGroupRow.setHideSensitive(false, true, 0, 0);
104 assertTrue(mGroupRow.getChildrenContainer().getVisibleHeader().getVisibility()
Selim Cinek6fd06b52017-03-07 15:54:10 -0800105 == View.VISIBLE);
Selim Cinek1826d982017-03-06 20:47:37 -0800106 }
107
Selim Cinek817abe72017-05-24 11:08:55 -0700108 @Test
109 public void testUserLockedResetEvenWhenNoChildren() {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700110 mGroupRow.setUserLocked(true);
111 mGroupRow.removeAllChildren();
112 mGroupRow.setUserLocked(false);
113 assertFalse("The childrencontainer should not be userlocked but is, the state "
114 + "seems out of sync.", mGroupRow.getChildrenContainer().isUserLocked());
Selim Cinek817abe72017-05-24 11:08:55 -0700115 }
116
117 @Test
118 public void testReinflatedOnDensityChange() {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700119 mGroupRow.setUserLocked(true);
120 mGroupRow.removeAllChildren();
121 mGroupRow.setUserLocked(false);
Selim Cinek817abe72017-05-24 11:08:55 -0700122 NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700123 mGroupRow.setChildrenContainer(mockContainer);
124 mGroupRow.onDensityOrFontScaleChanged();
Selim Cinek817abe72017-05-24 11:08:55 -0700125 verify(mockContainer).reInflateViews(any(), any());
126 }
127
Lucas Dupinb6ed63b2017-05-30 16:17:42 -0700128 @Test
129 public void testIconColorShouldBeUpdatedWhenSensitive() throws Exception {
Kevin38ce6fa2018-10-17 16:00:14 -0700130 ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow(
131 FLAG_CONTENT_VIEW_ALL));
Lucas Dupinb6ed63b2017-05-30 16:17:42 -0700132 row.setSensitive(true, true);
133 row.setHideSensitive(true, false, 0, 0);
134 verify(row).updateShelfIconColor();
135 }
Selim Cinek5cf1d052017-06-01 17:36:46 -0700136
137 @Test
Selim Cineka7c69632017-06-07 15:51:29 -0700138 public void testIconColorShouldBeUpdatedWhenSettingDark() throws Exception {
139 ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow());
140 row.setDark(true, false, 0);
141 verify(row).updateShelfIconColor();
142 }
Ian Pedowitza27856d2017-06-07 17:47:38 -0700143
144 @Test
Kevind5022f92018-10-08 18:30:26 -0700145 public void testFreeContentViewWhenSafe() throws Exception {
146 ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_CONTENT_VIEW_ALL);
Kevind4660b22018-09-27 10:57:35 -0700147
Kevind5022f92018-10-08 18:30:26 -0700148 row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP);
Kevind4660b22018-09-27 10:57:35 -0700149
150 assertNull(row.getPrivateLayout().getHeadsUpChild());
151 }
152
153 @Test
Kevin38ce6fa2018-10-17 16:00:14 -0700154 public void setNeedsRedactionSetsInflationFlag() throws Exception {
155 ExpandableNotificationRow row = mNotificationTestHelper.createRow();
156
157 row.setNeedsRedaction(true);
158
159 assertTrue(row.getNotificationInflater().isInflationFlagSet(FLAG_CONTENT_VIEW_PUBLIC));
160 }
161
162 @Test
163 public void setNeedsRedactionFreesViewWhenFalse() throws Exception {
164 ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_CONTENT_VIEW_ALL);
165 row.setNeedsRedaction(true);
166 row.getPublicLayout().setVisibility(View.GONE);
167
168 row.setNeedsRedaction(false);
169
170 assertNull(row.getPublicLayout().getContractedChild());
171 }
172
173 @Test
Selim Cinek5cf1d052017-06-01 17:36:46 -0700174 public void testAboveShelfChangedListenerCalled() throws Exception {
175 ExpandableNotificationRow row = mNotificationTestHelper.createRow();
176 AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
177 row.setAboveShelfChangedListener(listener);
178 row.setHeadsUp(true);
179 verify(listener).onAboveShelfStateChanged(true);
180 }
181
182 @Test
183 public void testAboveShelfChangedListenerCalledPinned() throws Exception {
184 ExpandableNotificationRow row = mNotificationTestHelper.createRow();
185 AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
186 row.setAboveShelfChangedListener(listener);
187 row.setPinned(true);
188 verify(listener).onAboveShelfStateChanged(true);
189 }
190
191 @Test
192 public void testAboveShelfChangedListenerCalledHeadsUpGoingAway() throws Exception {
193 ExpandableNotificationRow row = mNotificationTestHelper.createRow();
194 AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
195 row.setAboveShelfChangedListener(listener);
196 row.setHeadsUpAnimatingAway(true);
197 verify(listener).onAboveShelfStateChanged(true);
198 }
199 @Test
200 public void testAboveShelfChangedListenerCalledWhenGoingBelow() throws Exception {
201 ExpandableNotificationRow row = mNotificationTestHelper.createRow();
202 row.setHeadsUp(true);
203 AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
204 row.setAboveShelfChangedListener(listener);
205 row.setAboveShelf(false);
206 verify(listener).onAboveShelfStateChanged(false);
207 }
Lucas Dupincecc7c22017-09-12 16:02:45 -0700208
209 @Test
210 public void testClickSound() throws Exception {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700211 assertTrue("Should play sounds by default.", mGroupRow.isSoundEffectsEnabled());
212 mGroupRow.setDark(true /* dark */, false /* fade */, 0 /* delay */);
213 mGroupRow.setSecureStateProvider(()-> false);
214 assertFalse("Shouldn't play sounds when dark and trusted.",
215 mGroupRow.isSoundEffectsEnabled());
216 mGroupRow.setSecureStateProvider(()-> true);
217 assertTrue("Should always play sounds when not trusted.",
218 mGroupRow.isSoundEffectsEnabled());
Lucas Dupincecc7c22017-09-12 16:02:45 -0700219 }
Julia Reynoldsfc640012018-02-21 12:25:27 -0500220
221 @Test
Rohan Shahc6990a02018-03-23 17:24:17 -0700222 public void testSetDismissed_longPressListenerRemoved() {
223 ExpandableNotificationRow.LongPressListener listener =
224 mock(ExpandableNotificationRow.LongPressListener.class);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700225 mGroupRow.setLongPressListener(listener);
226 mGroupRow.doLongClickCallback(0,0);
227 verify(listener, times(1)).onLongPress(eq(mGroupRow), eq(0), eq(0),
Rohan Shahc6990a02018-03-23 17:24:17 -0700228 any(NotificationMenuRowPlugin.MenuItem.class));
229 reset(listener);
230
Rohan Shah524cf7b2018-03-15 14:40:02 -0700231 mGroupRow.setDismissed(true);
232 mGroupRow.doLongClickCallback(0,0);
233 verify(listener, times(0)).onLongPress(eq(mGroupRow), eq(0), eq(0),
Rohan Shahc6990a02018-03-23 17:24:17 -0700234 any(NotificationMenuRowPlugin.MenuItem.class));
235 }
236
237 @Test
Julia Reynoldsb5867452018-02-28 16:31:35 -0500238 public void testShowAppOps_noHeader() {
Julia Reynoldsfc640012018-02-21 12:25:27 -0500239 // public notification is custom layout - no header
Rohan Shah524cf7b2018-03-15 14:40:02 -0700240 mGroupRow.setSensitive(true, true);
241 mGroupRow.setAppOpsOnClickListener(null);
242 mGroupRow.showAppOpsIcons(null);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500243 }
244
245 @Test
Julia Reynoldsb5867452018-02-28 16:31:35 -0500246 public void testShowAppOpsIcons_header() {
Julia Reynoldsfc640012018-02-21 12:25:27 -0500247 NotificationHeaderView mockHeader = mock(NotificationHeaderView.class);
248
249 NotificationContentView publicLayout = mock(NotificationContentView.class);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700250 mGroupRow.setPublicLayout(publicLayout);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500251 NotificationContentView privateLayout = mock(NotificationContentView.class);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700252 mGroupRow.setPrivateLayout(privateLayout);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500253 NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
254 when(mockContainer.getNotificationChildCount()).thenReturn(1);
255 when(mockContainer.getHeaderView()).thenReturn(mockHeader);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700256 mGroupRow.setChildrenContainer(mockContainer);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500257
258 ArraySet<Integer> ops = new ArraySet<>();
259 ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700260 mGroupRow.showAppOpsIcons(ops);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500261
262 verify(mockHeader, times(1)).showAppOpsIcons(ops);
263 verify(privateLayout, times(1)).showAppOpsIcons(ops);
264 verify(publicLayout, times(1)).showAppOpsIcons(ops);
265
266 }
Julia Reynoldsb5867452018-02-28 16:31:35 -0500267
268 @Test
269 public void testAppOpsOnClick() {
270 ExpandableNotificationRow.OnAppOpsClickListener l = mock(
271 ExpandableNotificationRow.OnAppOpsClickListener.class);
272 View view = mock(View.class);
273
Rohan Shah524cf7b2018-03-15 14:40:02 -0700274 mGroupRow.setAppOpsOnClickListener(l);
Julia Reynoldsb5867452018-02-28 16:31:35 -0500275
Rohan Shah524cf7b2018-03-15 14:40:02 -0700276 mGroupRow.getAppOpsOnClickListener().onClick(view);
Julia Reynoldsb5867452018-02-28 16:31:35 -0500277 verify(l, times(1)).onClick(any(), anyInt(), anyInt(), any());
278 }
Selim Cinek8875de12018-03-22 10:14:32 -0700279
280 @Test
281 public void testHeadsUpAnimatingAwayListener() {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700282 mGroupRow.setHeadsUpAnimatingAway(true);
Selim Cinek8875de12018-03-22 10:14:32 -0700283 Assert.assertEquals(true, mHeadsUpAnimatingAway);
Rohan Shah524cf7b2018-03-15 14:40:02 -0700284 mGroupRow.setHeadsUpAnimatingAway(false);
Selim Cinek8875de12018-03-22 10:14:32 -0700285 Assert.assertEquals(false, mHeadsUpAnimatingAway);
286 }
Rohan Shah524cf7b2018-03-15 14:40:02 -0700287
288 @Test
289 public void testPerformDismissWithBlockingHelper_falseWhenBlockingHelperIsntShown() {
290 when(mBlockingHelperManager.perhapsShowBlockingHelper(
291 eq(mGroupRow), any(NotificationMenuRowPlugin.class))).thenReturn(false);
292
293 assertFalse(
294 mGroupRow.performDismissWithBlockingHelper(false /* fromAccessibility */));
295 }
296
297 @Test
298 public void testPerformDismissWithBlockingHelper_doesntPerformOnGroupSummary() {
299 ExpandableNotificationRow childRow = mGroupRow.getChildrenContainer().getViewAtPosition(0);
300 when(mBlockingHelperManager.perhapsShowBlockingHelper(eq(childRow), any(NotificationMenuRowPlugin.class)))
301 .thenReturn(true);
302
303 assertTrue(
304 childRow.performDismissWithBlockingHelper(false /* fromAccessibility */));
305
306 verify(mBlockingHelperManager, times(1))
307 .perhapsShowBlockingHelper(eq(childRow), any(NotificationMenuRowPlugin.class));
308 verify(mBlockingHelperManager, times(0))
309 .perhapsShowBlockingHelper(eq(mGroupRow), any(NotificationMenuRowPlugin.class));
310 }
311
312 @Test
313 public void testIsBlockingHelperShowing_isCorrectlyUpdated() {
314 mGroupRow.setBlockingHelperShowing(true);
315 assertTrue(mGroupRow.isBlockingHelperShowing());
316
317 mGroupRow.setBlockingHelperShowing(false);
318 assertFalse(mGroupRow.isBlockingHelperShowing());
319 }
Rohan Shah63411fc2018-03-28 19:05:52 -0700320
321 @Test
322 public void testGetNumUniqueChildren_defaultChannel() {
323 assertEquals(1, mGroupRow.getNumUniqueChannels());
324 }
325
326 @Test
327 public void testGetNumUniqueChildren_multiChannel() {
328 List<ExpandableNotificationRow> childRows =
329 mGroupRow.getChildrenContainer().getNotificationChildren();
330 // Give each child a unique channel id/name.
331 int i = 0;
332 for (ExpandableNotificationRow childRow : childRows) {
333 childRow.getEntry().channel =
334 new NotificationChannel("id" + i, "dinnertime" + i, IMPORTANCE_DEFAULT);
335 i++;
336 }
337
338 assertEquals(3, mGroupRow.getNumUniqueChannels());
339 }
shawnlin4fbeac42018-04-30 20:32:40 +0800340
341 @Test
342 public void testIconScrollXAfterTranslationAndReset() throws Exception {
343 mGroupRow.setTranslation(50);
344 assertEquals(50, -mGroupRow.getEntry().expandedIcon.getScrollX());
345
346 mGroupRow.resetTranslation();
347 assertEquals(0, mGroupRow.getEntry().expandedIcon.getScrollX());
348 }
Aaron Heuckroth17ce40e2018-06-19 15:44:40 -0400349
350 @Test
351 public void testIsExpanded_userExpanded() {
352 mGroupRow.setExpandable(true);
353 Assert.assertFalse(mGroupRow.isExpanded());
354 mGroupRow.setUserExpanded(true);
355 Assert.assertTrue(mGroupRow.isExpanded());
356 }
Selim Cinek2ffa02f2017-03-06 15:56:37 -0800357}