blob: 61388b6d0389ffbcd7424d6d4249fd6aa43ff945 [file] [log] [blame]
Julia Reynolds12ba4cf2020-01-10 16:01:38 -05001/*
2 * Copyright (C) 2020 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.statusbar.notification.row;
18
Julia Reynolds8d257092020-04-15 15:57:21 -040019import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
20import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050021import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
22import static android.app.NotificationManager.IMPORTANCE_HIGH;
23import static android.app.NotificationManager.IMPORTANCE_LOW;
24import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME;
25import static android.view.View.GONE;
26import static android.view.View.VISIBLE;
27
Julia Reynoldsa856e492020-03-18 17:30:06 -040028import static com.google.common.truth.Truth.assertThat;
29
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050030import static junit.framework.Assert.assertEquals;
31import static junit.framework.Assert.assertFalse;
32import static junit.framework.Assert.assertTrue;
33
Dan Sandlerb11f2de2020-02-19 13:18:24 -050034import static org.mockito.ArgumentMatchers.anyBoolean;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050035import static org.mockito.Mockito.any;
36import static org.mockito.Mockito.anyInt;
37import static org.mockito.Mockito.anyString;
Evan Laird31ca5472020-04-08 17:45:24 -040038import static org.mockito.Mockito.atLeastOnce;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050039import static org.mockito.Mockito.doAnswer;
40import static org.mockito.Mockito.eq;
Evan Laird31ca5472020-04-08 17:45:24 -040041import static org.mockito.Mockito.mock;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050042import static org.mockito.Mockito.never;
43import static org.mockito.Mockito.times;
44import static org.mockito.Mockito.verify;
45import static org.mockito.Mockito.when;
46
47import android.app.INotificationManager;
48import android.app.Notification;
49import android.app.NotificationChannel;
50import android.app.NotificationChannelGroup;
51import android.app.PendingIntent;
52import android.app.Person;
Evan Laird31ca5472020-04-08 17:45:24 -040053import android.content.Context;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050054import android.content.Intent;
55import android.content.pm.ApplicationInfo;
56import android.content.pm.LauncherApps;
57import android.content.pm.PackageInfo;
58import android.content.pm.PackageManager;
59import android.content.pm.ShortcutInfo;
60import android.content.pm.ShortcutManager;
Dan Sandlerb11f2de2020-02-19 13:18:24 -050061import android.graphics.drawable.Drawable;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050062import android.graphics.drawable.Icon;
63import android.os.UserHandle;
64import android.service.notification.StatusBarNotification;
65import android.test.suitebuilder.annotation.SmallTest;
66import android.testing.AndroidTestingRunner;
67import android.testing.TestableLooper;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050068import android.view.LayoutInflater;
69import android.view.View;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050070import android.widget.ImageView;
71import android.widget.TextView;
72
73import com.android.internal.logging.MetricsLogger;
Julia Reynolds01c9da42020-02-14 14:17:58 -050074import com.android.settingslib.notification.ConversationIconFactory;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050075import com.android.systemui.Dependency;
Evan Laird31ca5472020-04-08 17:45:24 -040076import com.android.systemui.Prefs;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050077import com.android.systemui.R;
78import com.android.systemui.SysuiTestCase;
79import com.android.systemui.bubbles.BubbleController;
80import com.android.systemui.bubbles.BubblesTestActivity;
81import com.android.systemui.statusbar.SbnBuilder;
82import com.android.systemui.statusbar.notification.VisualStabilityManager;
83import com.android.systemui.statusbar.notification.collection.NotificationEntry;
84import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
Julia Reynoldse6fed502020-02-07 14:41:02 -050085import com.android.systemui.statusbar.phone.ShadeController;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050086
87import org.junit.Before;
88import org.junit.Rule;
89import org.junit.Test;
90import org.junit.runner.RunWith;
Evan Laird31ca5472020-04-08 17:45:24 -040091import org.mockito.Answers;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -050092import org.mockito.ArgumentCaptor;
93import org.mockito.Mock;
94import org.mockito.junit.MockitoJUnit;
95import org.mockito.junit.MockitoRule;
96import org.mockito.stubbing.Answer;
97
98import java.util.Arrays;
99import java.util.List;
100import java.util.concurrent.CountDownLatch;
101
Evan Laird31ca5472020-04-08 17:45:24 -0400102import javax.inject.Provider;
103
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500104@SmallTest
105@RunWith(AndroidTestingRunner.class)
106@TestableLooper.RunWithLooper
107public class NotificationConversationInfoTest extends SysuiTestCase {
108 private static final String TEST_PACKAGE_NAME = "test_package";
109 private static final String TEST_SYSTEM_PACKAGE_NAME = PRINT_SPOOLER_PACKAGE_NAME;
110 private static final int TEST_UID = 1;
111 private static final String TEST_CHANNEL = "test_channel";
112 private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME";
113 private static final String CONVERSATION_ID = "convo";
114
115 private TestableLooper mTestableLooper;
116 private NotificationConversationInfo mNotificationInfo;
117 private NotificationChannel mNotificationChannel;
118 private NotificationChannel mConversationChannel;
119 private StatusBarNotification mSbn;
120 private NotificationEntry mEntry;
121 private StatusBarNotification mBubbleSbn;
122 private NotificationEntry mBubbleEntry;
123 @Mock
124 private ShortcutInfo mShortcutInfo;
Julia Reynolds01c9da42020-02-14 14:17:58 -0500125 @Mock
Dan Sandlerb11f2de2020-02-19 13:18:24 -0500126 private Drawable mIconDrawable;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500127
128 @Rule
129 public MockitoRule mockito = MockitoJUnit.rule();
130 @Mock
131 private MetricsLogger mMetricsLogger;
132 @Mock
133 private INotificationManager mMockINotificationManager;
134 @Mock
135 private PackageManager mMockPackageManager;
136 @Mock
137 private VisualStabilityManager mVisualStabilityManager;
138 @Mock
139 private BubbleController mBubbleController;
140 @Mock
141 private LauncherApps mLauncherApps;
142 @Mock
143 private ShortcutManager mShortcutManager;
144 @Mock
145 private NotificationGuts mNotificationGuts;
Julia Reynoldse6fed502020-02-07 14:41:02 -0500146 @Mock
147 private ShadeController mShadeController;
Julia Reynolds01c9da42020-02-14 14:17:58 -0500148 @Mock
149 private ConversationIconFactory mIconFactory;
Evan Laird31ca5472020-04-08 17:45:24 -0400150 @Mock
151 private Context mUserContext;
152 @Mock(answer = Answers.RETURNS_SELF)
153 private PriorityOnboardingDialogController.Builder mBuilder;
154 private Provider<PriorityOnboardingDialogController.Builder> mBuilderProvider = () -> mBuilder;
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500155
156 @Before
157 public void setUp() throws Exception {
158 mTestableLooper = TestableLooper.get(this);
159
160 mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
161 mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
162 mDependency.injectTestDependency(BubbleController.class, mBubbleController);
Julia Reynoldse6fed502020-02-07 14:41:02 -0500163 mDependency.injectTestDependency(ShadeController.class, mShadeController);
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500164 // Inflate the layout
165 final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
166 mNotificationInfo = (NotificationConversationInfo) layoutInflater.inflate(
167 R.layout.notification_conversation_info,
168 null);
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500169 mNotificationInfo.setGutsParent(mNotificationGuts);
170 doAnswer((Answer<Object>) invocation -> {
171 mNotificationInfo.handleCloseControls(true, false);
172 return null;
173 }).when(mNotificationGuts).closeControls(anyInt(), anyInt(), eq(true), eq(false));
174 // Our view is never attached to a window so the View#post methods in NotificationInfo never
175 // get called. Setting this will skip the post and do the action immediately.
176 mNotificationInfo.mSkipPost = true;
177
178 // PackageManager must return a packageInfo and applicationInfo.
179 final PackageInfo packageInfo = new PackageInfo();
180 packageInfo.packageName = TEST_PACKAGE_NAME;
181 when(mMockPackageManager.getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt()))
182 .thenReturn(packageInfo);
183 final ApplicationInfo applicationInfo = new ApplicationInfo();
184 applicationInfo.uid = TEST_UID; // non-zero
185 when(mMockPackageManager.getApplicationInfo(eq(TEST_PACKAGE_NAME), anyInt())).thenReturn(
186 applicationInfo);
187 final PackageInfo systemPackageInfo = new PackageInfo();
188 systemPackageInfo.packageName = TEST_SYSTEM_PACKAGE_NAME;
189 when(mMockPackageManager.getPackageInfo(eq(TEST_SYSTEM_PACKAGE_NAME), anyInt()))
190 .thenReturn(systemPackageInfo);
191 when(mMockPackageManager.getPackageInfo(eq("android"), anyInt()))
192 .thenReturn(packageInfo);
193
194 when(mShortcutInfo.getShortLabel()).thenReturn("Convo name");
195 List<ShortcutInfo> shortcuts = Arrays.asList(mShortcutInfo);
196 when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
Dan Sandlerb11f2de2020-02-19 13:18:24 -0500197 when(mIconFactory.getConversationDrawable(
198 any(ShortcutInfo.class), anyString(), anyInt(), anyBoolean()))
199 .thenReturn(mIconDrawable);
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500200
201 mNotificationChannel = new NotificationChannel(
202 TEST_CHANNEL, TEST_CHANNEL_NAME, IMPORTANCE_LOW);
203
204 Notification notification = new Notification.Builder(mContext, mNotificationChannel.getId())
205 .setShortcutId(CONVERSATION_ID)
206 .setStyle(new Notification.MessagingStyle(new Person.Builder().setName("m").build())
207 .addMessage(new Notification.MessagingStyle.Message(
208 "hello!", 1000, new Person.Builder().setName("other").build())))
209 .build();
210 mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
211 notification, UserHandle.CURRENT, null, 0);
Julia Reynolds138111f2020-02-26 11:17:39 -0500212 mEntry = new NotificationEntryBuilder().setSbn(mSbn).setShortcutInfo(mShortcutInfo).build();
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500213
214 PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0,
215 new Intent(mContext, BubblesTestActivity.class), 0);
216 mBubbleSbn = new SbnBuilder(mSbn).setBubbleMetadata(
Mady Melloraa9ce172020-03-17 10:34:20 -0700217 new Notification.BubbleMetadata.Builder(bubbleIntent,
218 Icon.createWithResource(mContext, R.drawable.android)).build())
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500219 .build();
Julia Reynolds138111f2020-02-26 11:17:39 -0500220 mBubbleEntry = new NotificationEntryBuilder()
221 .setSbn(mBubbleSbn)
222 .setShortcutInfo(mShortcutInfo)
223 .build();
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500224
225 mConversationChannel = new NotificationChannel(
226 TEST_CHANNEL + " : " + CONVERSATION_ID, TEST_CHANNEL_NAME, IMPORTANCE_LOW);
227 mConversationChannel.setConversationId(TEST_CHANNEL, CONVERSATION_ID);
228 when(mMockINotificationManager.getConversationNotificationChannel(anyString(), anyInt(),
229 anyString(), eq(TEST_CHANNEL), eq(false), eq(CONVERSATION_ID)))
230 .thenReturn(mConversationChannel);
231 }
232
233 @Test
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500234 public void testBindNotification_SetsShortcutIcon() {
235 mNotificationInfo.bindNotification(
236 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500237 mMockPackageManager,
238 mMockINotificationManager,
239 mVisualStabilityManager,
240 TEST_PACKAGE_NAME,
241 mNotificationChannel,
242 mEntry,
243 null,
244 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500245 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400246 mUserContext,
247 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500248 true);
249 final ImageView view = mNotificationInfo.findViewById(R.id.conversation_icon);
Dan Sandlerb11f2de2020-02-19 13:18:24 -0500250 assertEquals(mIconDrawable, view.getDrawable());
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500251 }
252
253 @Test
254 public void testBindNotification_SetsTextApplicationName() {
255 when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
256 mNotificationInfo.bindNotification(
257 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500258 mMockPackageManager,
259 mMockINotificationManager,
260 mVisualStabilityManager,
261 TEST_PACKAGE_NAME,
262 mNotificationChannel,
263 mEntry,
264 null,
265 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500266 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400267 mUserContext,
268 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500269 true);
270 final TextView textView = mNotificationInfo.findViewById(R.id.pkg_name);
271 assertTrue(textView.getText().toString().contains("App Name"));
272 assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
273 }
Julia Reynoldsf2acd602020-01-21 16:01:25 -0500274/**
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500275 @Test
276 public void testBindNotification_SetsTextChannelName() {
277 mNotificationInfo.bindNotification(
278 mShortcutManager,
279 mLauncherApps,
280 mMockPackageManager,
281 mMockINotificationManager,
282 mVisualStabilityManager,
283 TEST_PACKAGE_NAME,
284 mNotificationChannel,
285 mEntry,
286 null,
287 null,
288 null,
289 true);
290 final TextView textView = mNotificationInfo.findViewById(R.id.parent_channel_name);
291 assertTrue(textView.getText().toString().contains(mNotificationChannel.getName()));
292 assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
293 }
Julia Reynoldsf2acd602020-01-21 16:01:25 -0500294*/
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500295 @Test
296 public void testBindNotification_SetsTextGroupName() throws Exception {
297 NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
298 when(mMockINotificationManager.getNotificationChannelGroupForPackage(
299 anyString(), anyString(), anyInt())).thenReturn(group);
300 mNotificationChannel.setGroup(group.getId());
301 mConversationChannel.setGroup(group.getId());
302
303 mNotificationInfo.bindNotification(
304 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500305 mMockPackageManager,
306 mMockINotificationManager,
307 mVisualStabilityManager,
308 TEST_PACKAGE_NAME,
309 mNotificationChannel,
310 mEntry,
311 null,
312 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500313 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400314 mUserContext,
315 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500316 true);
317 final TextView textView = mNotificationInfo.findViewById(R.id.group_name);
318 assertTrue(textView.getText().toString().contains(group.getName()));
319 assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
320 assertEquals(VISIBLE, textView.getVisibility());
321 assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.group_divider).getVisibility());
322 }
323
324 @Test
325 public void testBindNotification_GroupNameHiddenIfNoGroup() {
326 mNotificationInfo.bindNotification(
327 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500328 mMockPackageManager,
329 mMockINotificationManager,
330 mVisualStabilityManager,
331 TEST_PACKAGE_NAME,
332 mNotificationChannel,
333 mEntry,
334 null,
335 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500336 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400337 mUserContext,
338 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500339 true);
340 final TextView textView = mNotificationInfo.findViewById(R.id.group_name);
341 assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
342 assertEquals(GONE, textView.getVisibility());
343 assertEquals(GONE, mNotificationInfo.findViewById(R.id.group_divider).getVisibility());
344 }
345
346 @Test
347 public void testBindNotification_noDelegate() {
348 mNotificationInfo.bindNotification(
349 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500350 mMockPackageManager,
351 mMockINotificationManager,
352 mVisualStabilityManager,
353 TEST_PACKAGE_NAME,
354 mNotificationChannel,
355 mEntry,
356 null,
357 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500358 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400359 mUserContext,
360 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500361 true);
362 final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
363 assertEquals(GONE, nameView.getVisibility());
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500364 }
365
366 @Test
367 public void testBindNotification_delegate() throws Exception {
368 mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, "other", 0, null, TEST_UID, 0,
369 mSbn.getNotification(), UserHandle.CURRENT, null, 0);
370 final ApplicationInfo applicationInfo = new ApplicationInfo();
371 applicationInfo.uid = 7; // non-zero
372 when(mMockPackageManager.getApplicationInfo(eq("other"), anyInt())).thenReturn(
373 applicationInfo);
374 when(mMockPackageManager.getApplicationLabel(any())).thenReturn("Other");
375
376 NotificationEntry entry = new NotificationEntryBuilder().setSbn(mSbn).build();
377 mNotificationInfo.bindNotification(
378 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500379 mMockPackageManager,
380 mMockINotificationManager,
381 mVisualStabilityManager,
382 TEST_PACKAGE_NAME,
383 mNotificationChannel,
384 entry,
385 null,
386 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500387 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400388 mUserContext,
389 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500390 true);
391 final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
392 assertEquals(VISIBLE, nameView.getVisibility());
393 assertTrue(nameView.getText().toString().contains("Proxied"));
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500394 }
395
396 @Test
397 public void testBindNotification_SetsOnClickListenerForSettings() {
398 final CountDownLatch latch = new CountDownLatch(1);
399 mNotificationInfo.bindNotification(
400 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500401 mMockPackageManager,
402 mMockINotificationManager,
403 mVisualStabilityManager,
404 TEST_PACKAGE_NAME,
405 mNotificationChannel,
406 mEntry,
407 (View v, NotificationChannel c, int appUid) -> {
408 assertEquals(mConversationChannel, c);
409 latch.countDown();
410 },
411 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500412 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400413 mUserContext,
414 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500415 true);
416
417 final View settingsButton = mNotificationInfo.findViewById(R.id.info);
418 settingsButton.performClick();
419 // Verify that listener was triggered.
420 assertEquals(0, latch.getCount());
421 }
422
423 @Test
424 public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() {
425 mNotificationInfo.bindNotification(
426 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500427 mMockPackageManager,
428 mMockINotificationManager,
429 mVisualStabilityManager,
430 TEST_PACKAGE_NAME,
431 mNotificationChannel,
432 mEntry,
433 null,
434 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500435 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400436 mUserContext,
437 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500438 true);
439 final View settingsButton = mNotificationInfo.findViewById(R.id.info);
440 assertTrue(settingsButton.getVisibility() != View.VISIBLE);
441 }
442
443 @Test
444 public void testBindNotification_SettingsButtonInvisibleWhenDeviceUnprovisioned() {
445 final CountDownLatch latch = new CountDownLatch(1);
446 mNotificationInfo.bindNotification(
447 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500448 mMockPackageManager,
449 mMockINotificationManager,
450 mVisualStabilityManager,
451 TEST_PACKAGE_NAME,
452 mNotificationChannel,
453 mEntry,
454 (View v, NotificationChannel c, int appUid) -> {
455 assertEquals(mNotificationChannel, c);
456 latch.countDown();
457 },
458 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500459 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400460 mUserContext,
461 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500462 false);
463 final View settingsButton = mNotificationInfo.findViewById(R.id.info);
464 assertTrue(settingsButton.getVisibility() != View.VISIBLE);
465 }
466
467 @Test
Julia Reynoldsa856e492020-03-18 17:30:06 -0400468 public void testBindNotification_silentSelected_isFave_isSilent() {
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500469 mConversationChannel.setImportance(IMPORTANCE_LOW);
Julia Reynoldsa856e492020-03-18 17:30:06 -0400470 mConversationChannel.setImportantConversation(true);
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500471 mNotificationInfo.bindNotification(
472 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500473 mMockPackageManager,
474 mMockINotificationManager,
475 mVisualStabilityManager,
476 TEST_PACKAGE_NAME,
477 mNotificationChannel,
478 mEntry,
479 null,
480 null,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400481 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400482 mUserContext,
483 mBuilderProvider,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400484 true);
485 View view = mNotificationInfo.findViewById(R.id.silence);
486 assertThat(view.isSelected()).isTrue();
487 }
488
489 @Test
Julia Reynolds8d257092020-04-15 15:57:21 -0400490 public void testBindNotification_defaultSelected_notFave_notSilent() throws Exception {
491 when(mMockINotificationManager.getBubblePreferenceForPackage(anyString(), anyInt()))
492 .thenReturn(BUBBLE_PREFERENCE_SELECTED);
Julia Reynoldsa856e492020-03-18 17:30:06 -0400493 mConversationChannel.setImportance(IMPORTANCE_HIGH);
494 mConversationChannel.setImportantConversation(false);
495 mConversationChannel.setAllowBubbles(true);
496 mNotificationInfo.bindNotification(
497 mShortcutManager,
498 mMockPackageManager,
499 mMockINotificationManager,
500 mVisualStabilityManager,
501 TEST_PACKAGE_NAME,
502 mNotificationChannel,
503 mEntry,
504 null,
505 null,
506 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400507 mUserContext,
508 mBuilderProvider,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400509 true);
510 View view = mNotificationInfo.findViewById(R.id.default_behavior);
511 assertThat(view.isSelected()).isTrue();
Julia Reynolds8d257092020-04-15 15:57:21 -0400512 assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo(
513 mContext.getString(R.string.notification_channel_summary_default));
514 }
515
516 @Test
517 public void testBindNotification_default_allCanBubble() throws Exception {
518 when(mMockINotificationManager.getBubblePreferenceForPackage(anyString(), anyInt()))
519 .thenReturn(BUBBLE_PREFERENCE_ALL);
520 when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
521 mConversationChannel.setImportance(IMPORTANCE_HIGH);
522 mConversationChannel.setImportantConversation(false);
523 mConversationChannel.setAllowBubbles(true);
524 mNotificationInfo.bindNotification(
525 mShortcutManager,
526 mMockPackageManager,
527 mMockINotificationManager,
528 mVisualStabilityManager,
529 TEST_PACKAGE_NAME,
530 mNotificationChannel,
531 mEntry,
532 null,
533 null,
534 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400535 mUserContext,
536 mBuilderProvider,
Julia Reynolds8d257092020-04-15 15:57:21 -0400537 true);
538 View view = mNotificationInfo.findViewById(R.id.default_behavior);
539 assertThat(view.isSelected()).isTrue();
540 assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo(
541 mContext.getString(R.string.notification_channel_summary_default_with_bubbles,
542 "App Name"));
Julia Reynoldsa856e492020-03-18 17:30:06 -0400543 }
544
545 @Test
546 public void testFavorite() throws Exception {
547 mConversationChannel.setAllowBubbles(false);
548 mConversationChannel.setImportance(IMPORTANCE_LOW);
549 mConversationChannel.setImportantConversation(false);
550
551 mNotificationInfo.bindNotification(
552 mShortcutManager,
553 mMockPackageManager,
554 mMockINotificationManager,
555 mVisualStabilityManager,
556 TEST_PACKAGE_NAME,
557 mNotificationChannel,
558 mEntry,
559 null,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500560 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500561 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400562 mUserContext,
563 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500564 true);
565
Julia Reynoldsa856e492020-03-18 17:30:06 -0400566 View fave = mNotificationInfo.findViewById(R.id.priority);
567 fave.performClick();
568 mTestableLooper.processAllMessages();
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500569
Julia Reynoldsa856e492020-03-18 17:30:06 -0400570 // silence subtext visible, others not
571 assertThat(mNotificationInfo.findViewById(R.id.priority_summary).getVisibility())
572 .isEqualTo(VISIBLE);
573 assertThat(mNotificationInfo.findViewById(R.id.default_summary).getVisibility())
574 .isEqualTo(GONE);
575 assertThat(mNotificationInfo.findViewById(R.id.silence_summary).getVisibility())
576 .isEqualTo(GONE);
577
578 // no changes until hit done
579 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
580 anyString(), anyInt(), any());
581 assertFalse(mConversationChannel.isImportantConversation());
582 assertFalse(mConversationChannel.canBubble());
583 assertEquals(IMPORTANCE_LOW, mConversationChannel.getImportance());
584 }
585
586 @Test
587 public void testDefault() throws Exception {
588 mConversationChannel.setAllowBubbles(false);
589 mConversationChannel.setImportance(IMPORTANCE_LOW);
590 mConversationChannel.setImportantConversation(false);
591 mNotificationInfo.bindNotification(
592 mShortcutManager,
593 mMockPackageManager,
594 mMockINotificationManager,
595 mVisualStabilityManager,
596 TEST_PACKAGE_NAME,
597 mNotificationChannel,
598 mEntry,
599 null,
600 null,
601 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400602 mUserContext,
603 mBuilderProvider,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400604 true);
605
606 mNotificationInfo.findViewById(R.id.default_behavior).performClick();
607 mTestableLooper.processAllMessages();
608
609 // silence subtext visible, others not
610 assertThat(mNotificationInfo.findViewById(R.id.priority_summary).getVisibility())
611 .isEqualTo(GONE);
612 assertThat(mNotificationInfo.findViewById(R.id.default_summary).getVisibility())
613 .isEqualTo(VISIBLE);
614 assertThat(mNotificationInfo.findViewById(R.id.silence_summary).getVisibility())
615 .isEqualTo(GONE);
616
617 // no changes until hit done
618 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
619 anyString(), anyInt(), any());
620 assertFalse(mConversationChannel.isImportantConversation());
621 assertFalse(mConversationChannel.canBubble());
622 assertEquals(IMPORTANCE_LOW, mConversationChannel.getImportance());
623 }
624
625 @Test
626 public void testSilence() throws Exception {
627 mConversationChannel.setImportance(IMPORTANCE_DEFAULT);
628 mConversationChannel.setImportantConversation(false);
629
630 mNotificationInfo.bindNotification(
631 mShortcutManager,
632 mMockPackageManager,
633 mMockINotificationManager,
634 mVisualStabilityManager,
635 TEST_PACKAGE_NAME,
636 mNotificationChannel,
637 mEntry,
638 null,
639 null,
640 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400641 mUserContext,
642 mBuilderProvider,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400643 true);
644
645 View silence = mNotificationInfo.findViewById(R.id.silence);
646
647 silence.performClick();
648 mTestableLooper.processAllMessages();
649
650 // silence subtext visible, others not
651 assertThat(mNotificationInfo.findViewById(R.id.priority_summary).getVisibility())
652 .isEqualTo(GONE);
653 assertThat(mNotificationInfo.findViewById(R.id.default_summary).getVisibility())
654 .isEqualTo(GONE);
655 assertThat(mNotificationInfo.findViewById(R.id.silence_summary).getVisibility())
656 .isEqualTo(VISIBLE);
657
658 // no changes until save
659 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
660 anyString(), anyInt(), any());
661 assertEquals(IMPORTANCE_DEFAULT, mConversationChannel.getImportance());
662 }
663
664 @Test
665 public void testFavorite_andSave() throws Exception {
666 mConversationChannel.setAllowBubbles(false);
667 mConversationChannel.setImportance(IMPORTANCE_LOW);
668 mConversationChannel.setImportantConversation(false);
669
670 mNotificationInfo.bindNotification(
671 mShortcutManager,
672 mMockPackageManager,
673 mMockINotificationManager,
674 mVisualStabilityManager,
675 TEST_PACKAGE_NAME,
676 mNotificationChannel,
677 mEntry,
678 null,
679 null,
680 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400681 mUserContext,
682 mBuilderProvider,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400683 true);
684
685 View fave = mNotificationInfo.findViewById(R.id.priority);
686 fave.performClick();
687 mNotificationInfo.findViewById(R.id.done).performClick();
688 mTestableLooper.processAllMessages();
689
690 ArgumentCaptor<NotificationChannel> captor =
691 ArgumentCaptor.forClass(NotificationChannel.class);
692 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
693 anyString(), anyInt(), captor.capture());
694 assertTrue(captor.getValue().isImportantConversation());
695 assertTrue(captor.getValue().canBubble());
696 assertEquals(IMPORTANCE_DEFAULT, captor.getValue().getImportance());
697 }
698
699 @Test
700 public void testFavorite_andSave_doesNotLowerImportance() throws Exception {
701 mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
702 mConversationChannel.setImportance(9);
703
704 mNotificationInfo.bindNotification(
705 mShortcutManager,
706 mMockPackageManager,
707 mMockINotificationManager,
708 mVisualStabilityManager,
709 TEST_PACKAGE_NAME,
710 mNotificationChannel,
711 mEntry,
712 null,
713 null,
714 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400715 mUserContext,
716 mBuilderProvider,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400717 true);
718
719 View fave = mNotificationInfo.findViewById(R.id.priority);
720 fave.performClick();
721 mNotificationInfo.findViewById(R.id.done).performClick();
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500722 mTestableLooper.processAllMessages();
723
724 ArgumentCaptor<NotificationChannel> captor =
725 ArgumentCaptor.forClass(NotificationChannel.class);
726 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
727 anyString(), anyInt(), captor.capture());
728 assertEquals(IMPORTANCE_HIGH, captor.getValue().getImportance());
729 }
730
731 @Test
Julia Reynoldsa856e492020-03-18 17:30:06 -0400732 public void testDefault_andSave() throws Exception {
733 mConversationChannel.setAllowBubbles(true);
734 mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
735 mConversationChannel.setImportantConversation(true);
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500736 mNotificationInfo.bindNotification(
737 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500738 mMockPackageManager,
739 mMockINotificationManager,
740 mVisualStabilityManager,
741 TEST_PACKAGE_NAME,
742 mNotificationChannel,
743 mEntry,
744 null,
745 null,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400746 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400747 mUserContext,
748 mBuilderProvider,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400749 true);
750
751 mNotificationInfo.findViewById(R.id.default_behavior).performClick();
752 mNotificationInfo.findViewById(R.id.done).performClick();
753 mTestableLooper.processAllMessages();
754
755 ArgumentCaptor<NotificationChannel> captor =
756 ArgumentCaptor.forClass(NotificationChannel.class);
757 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
758 anyString(), anyInt(), captor.capture());
759 assertFalse(captor.getValue().isImportantConversation());
760 assertFalse(captor.getValue().canBubble());
761 assertEquals(IMPORTANCE_HIGH, captor.getValue().getImportance());
762 }
763
764 @Test
765 public void testDefault_andSave_doesNotChangeNonImportantBubbling() throws Exception {
766 mConversationChannel.setAllowBubbles(true);
767 mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
768 mConversationChannel.setImportantConversation(false);
769 mNotificationInfo.bindNotification(
770 mShortcutManager,
771 mMockPackageManager,
772 mMockINotificationManager,
773 mVisualStabilityManager,
774 TEST_PACKAGE_NAME,
775 mNotificationChannel,
776 mEntry,
777 null,
778 null,
779 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400780 mUserContext,
781 mBuilderProvider,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400782 true);
783
784 mNotificationInfo.findViewById(R.id.default_behavior).performClick();
785 mNotificationInfo.findViewById(R.id.done).performClick();
786 mTestableLooper.processAllMessages();
787
788 ArgumentCaptor<NotificationChannel> captor =
789 ArgumentCaptor.forClass(NotificationChannel.class);
790 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
791 anyString(), anyInt(), captor.capture());
792 assertFalse(captor.getValue().isImportantConversation());
793 assertTrue(captor.getValue().canBubble());
794 assertEquals(IMPORTANCE_HIGH, captor.getValue().getImportance());
795 }
796
797 @Test
798 public void testDefault_andSave_doesNotDemoteImportance() throws Exception {
799 mConversationChannel.setImportance(9);
800 mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
801
802 mNotificationInfo.bindNotification(
803 mShortcutManager,
804 mMockPackageManager,
805 mMockINotificationManager,
806 mVisualStabilityManager,
807 TEST_PACKAGE_NAME,
808 mNotificationChannel,
809 mEntry,
810 null,
811 null,
812 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400813 mUserContext,
814 mBuilderProvider,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400815 true);
816
817 mNotificationInfo.findViewById(R.id.default_behavior).performClick();
818 mNotificationInfo.findViewById(R.id.done).performClick();
819 mTestableLooper.processAllMessages();
820
821 ArgumentCaptor<NotificationChannel> captor =
822 ArgumentCaptor.forClass(NotificationChannel.class);
823 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
824 anyString(), anyInt(), captor.capture());
825 assertEquals(IMPORTANCE_HIGH, captor.getValue().getImportance());
826 }
827
828 @Test
829 public void testSilence_andSave() throws Exception {
830 mConversationChannel.setImportance(IMPORTANCE_DEFAULT);
831 mConversationChannel.setImportantConversation(true);
832 mConversationChannel.setAllowBubbles(true);
833
834 mNotificationInfo.bindNotification(
835 mShortcutManager,
836 mMockPackageManager,
837 mMockINotificationManager,
838 mVisualStabilityManager,
839 TEST_PACKAGE_NAME,
840 mNotificationChannel,
841 mEntry,
842 null,
843 null,
844 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400845 mUserContext,
846 mBuilderProvider,
Julia Reynoldsa856e492020-03-18 17:30:06 -0400847 true);
848
849 View silence = mNotificationInfo.findViewById(R.id.silence);
850 silence.performClick();
851 mNotificationInfo.findViewById(R.id.done).performClick();
852 mTestableLooper.processAllMessages();
853
854 ArgumentCaptor<NotificationChannel> captor =
855 ArgumentCaptor.forClass(NotificationChannel.class);
856 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
857 anyString(), anyInt(), captor.capture());
858 assertFalse(captor.getValue().isImportantConversation());
859 assertFalse(captor.getValue().canBubble());
860 assertEquals(IMPORTANCE_LOW, captor.getValue().getImportance());
861 }
862
863 @Test
864 public void testBindNotification_createsNewChannel() throws Exception {
865 mNotificationInfo.bindNotification(
866 mShortcutManager,
867 mMockPackageManager,
868 mMockINotificationManager,
869 mVisualStabilityManager,
870 TEST_PACKAGE_NAME,
871 mNotificationChannel,
872 mEntry,
873 null,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500874 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500875 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400876 mUserContext,
877 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500878 true);
Julia Reynolds01c9da42020-02-14 14:17:58 -0500879
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500880 verify(mMockINotificationManager, times(1)).createConversationNotificationChannelForPackage(
Julia Reynolds7c267522020-01-16 11:26:41 -0500881 anyString(), anyInt(), anyString(), any(), eq(CONVERSATION_ID));
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500882 }
883
884 @Test
885 public void testBindNotification_doesNotCreateNewChannelIfExists() throws Exception {
886 mNotificationChannel.setConversationId("", CONVERSATION_ID);
887 mNotificationInfo.bindNotification(
888 mShortcutManager,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500889 mMockPackageManager,
890 mMockINotificationManager,
891 mVisualStabilityManager,
892 TEST_PACKAGE_NAME,
893 mNotificationChannel,
894 mEntry,
895 null,
896 null,
Julia Reynolds01c9da42020-02-14 14:17:58 -0500897 mIconFactory,
Evan Laird31ca5472020-04-08 17:45:24 -0400898 mUserContext,
899 mBuilderProvider,
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500900 true);
Julia Reynolds01c9da42020-02-14 14:17:58 -0500901
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500902 verify(mMockINotificationManager, never()).createConversationNotificationChannelForPackage(
Julia Reynolds7c267522020-01-16 11:26:41 -0500903 anyString(), anyInt(), anyString(), any(), eq(CONVERSATION_ID));
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500904 }
Evan Laird31ca5472020-04-08 17:45:24 -0400905
906 @Test
907 public void testSelectPriorityPresentsOnboarding_firstTime() {
908 // GIVEN pref is false
909 Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING, false);
910
911 // GIVEN the priority onboarding screen is present
912 PriorityOnboardingDialogController.Builder b =
913 new PriorityOnboardingDialogController.Builder();
914 PriorityOnboardingDialogController controller =
915 mock(PriorityOnboardingDialogController.class);
916 when(b.build()).thenReturn(controller);
917
918 // GIVEN the user is changing conversation settings
919 when(mBuilderProvider.get()).thenReturn(b);
920 mNotificationInfo.bindNotification(
921 mShortcutManager,
922 mMockPackageManager,
923 mMockINotificationManager,
924 mVisualStabilityManager,
925 TEST_PACKAGE_NAME,
926 mNotificationChannel,
927 mEntry,
928 null,
929 null,
930 mIconFactory,
931 mUserContext,
932 mBuilderProvider,
933 true);
934
935 // WHEN user clicks "priority"
936 mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
937
938 // THEN the user is presented with the priority onboarding screen
939 verify(controller, atLeastOnce()).show();
940 }
941
942 @Test
943 public void testSelectPriorityDoesNotShowOnboarding_secondTime() {
944 //WHEN pref is true
945 Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING, true);
946
947 PriorityOnboardingDialogController.Builder b =
948 new PriorityOnboardingDialogController.Builder();
949 PriorityOnboardingDialogController controller =
950 mock(PriorityOnboardingDialogController.class);
951 when(b.build()).thenReturn(controller);
952
953 when(mBuilderProvider.get()).thenReturn(b);
954 mNotificationInfo.bindNotification(
955 mShortcutManager,
956 mMockPackageManager,
957 mMockINotificationManager,
958 mVisualStabilityManager,
959 TEST_PACKAGE_NAME,
960 mNotificationChannel,
961 mEntry,
962 null,
963 null,
964 mIconFactory,
965 mUserContext,
966 mBuilderProvider,
967 true);
968
969 // WHEN user clicks "priority"
970 mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
971
972 // THEN the user is presented with the priority onboarding screen
973 verify(controller, never()).show();
974 }
Julia Reynolds12ba4cf2020-01-10 16:01:38 -0500975}