1 /*
2  * Copyright (C) 2016 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 
17 package com.android.systemui.statusbar.notification.row;
18 
19 import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO;
20 import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
21 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
22 import static android.app.NotificationManager.IMPORTANCE_LOW;
23 import static android.app.NotificationManager.IMPORTANCE_MIN;
24 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
25 import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME;
26 import static android.view.View.GONE;
27 import static android.view.View.VISIBLE;
28 
29 import static junit.framework.Assert.assertEquals;
30 import static junit.framework.Assert.assertFalse;
31 import static junit.framework.Assert.assertTrue;
32 
33 import static org.mockito.Mockito.any;
34 import static org.mockito.Mockito.anyBoolean;
35 import static org.mockito.Mockito.anyInt;
36 import static org.mockito.Mockito.anyString;
37 import static org.mockito.Mockito.eq;
38 import static org.mockito.Mockito.mock;
39 import static org.mockito.Mockito.never;
40 import static org.mockito.Mockito.times;
41 import static org.mockito.Mockito.verify;
42 import static org.mockito.Mockito.when;
43 
44 import android.app.INotificationManager;
45 import android.app.Notification;
46 import android.app.NotificationChannel;
47 import android.app.NotificationChannelGroup;
48 import android.app.PendingIntent;
49 import android.app.Person;
50 import android.content.pm.ApplicationInfo;
51 import android.content.pm.PackageInfo;
52 import android.content.pm.PackageManager;
53 import android.graphics.drawable.Drawable;
54 import android.os.RemoteException;
55 import android.os.UserHandle;
56 import android.service.notification.StatusBarNotification;
57 import android.telecom.TelecomManager;
58 import android.testing.TestableLooper;
59 import android.view.LayoutInflater;
60 import android.view.View;
61 import android.widget.ImageView;
62 import android.widget.TextView;
63 
64 import androidx.test.ext.junit.runners.AndroidJUnit4;
65 import androidx.test.filters.SmallTest;
66 
67 import com.android.internal.logging.MetricsLogger;
68 import com.android.internal.logging.testing.UiEventLoggerFake;
69 import com.android.systemui.Dependency;
70 import com.android.systemui.SysuiTestCase;
71 import com.android.systemui.res.R;
72 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
73 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
74 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
75 
76 import org.junit.Before;
77 import org.junit.Rule;
78 import org.junit.Test;
79 import org.junit.runner.RunWith;
80 import org.mockito.ArgumentCaptor;
81 import org.mockito.Mock;
82 import org.mockito.junit.MockitoJUnit;
83 import org.mockito.junit.MockitoRule;
84 
85 import java.util.concurrent.CountDownLatch;
86 
87 @SmallTest
88 @RunWith(AndroidJUnit4.class)
89 @TestableLooper.RunWithLooper
90 public class NotificationInfoTest extends SysuiTestCase {
91     private static final String TEST_PACKAGE_NAME = "test_package";
92     private static final String TEST_SYSTEM_PACKAGE_NAME = PRINT_SPOOLER_PACKAGE_NAME;
93     private static final int TEST_UID = 1;
94     private static final String TEST_CHANNEL = "test_channel";
95     private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME";
96 
97     private TestableLooper mTestableLooper;
98     private NotificationInfo mNotificationInfo;
99     private NotificationChannel mNotificationChannel;
100     private NotificationChannel mDefaultNotificationChannel;
101     private StatusBarNotification mSbn;
102     private NotificationEntry mEntry;
103     private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
104 
105     @Rule
106     public MockitoRule mockito = MockitoJUnit.rule();
107     @Mock
108     private MetricsLogger mMetricsLogger;
109     @Mock
110     private INotificationManager mMockINotificationManager;
111     @Mock
112     private PackageManager mMockPackageManager;
113     @Mock
114     private OnUserInteractionCallback mOnUserInteractionCallback;
115     @Mock
116     private ChannelEditorDialogController mChannelEditorDialogController;
117     @Mock
118     private AssistantFeedbackController mAssistantFeedbackController;
119     @Mock
120     private TelecomManager mTelecomManager;
121 
122     @Before
setUp()123     public void setUp() throws Exception {
124         mTestableLooper = TestableLooper.get(this);
125 
126         mContext.addMockSystemService(TelecomManager.class, mTelecomManager);
127 
128         mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
129         // Inflate the layout
130         final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
131         mNotificationInfo = (NotificationInfo) layoutInflater.inflate(R.layout.notification_info,
132                 null);
133         mNotificationInfo.setGutsParent(mock(NotificationGuts.class));
134         // Our view is never attached to a window so the View#post methods in NotificationInfo never
135         // get called. Setting this will skip the post and do the action immediately.
136         mNotificationInfo.mSkipPost = true;
137 
138         // PackageManager must return a packageInfo and applicationInfo.
139         final PackageInfo packageInfo = new PackageInfo();
140         packageInfo.packageName = TEST_PACKAGE_NAME;
141         when(mMockPackageManager.getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt()))
142                 .thenReturn(packageInfo);
143         final ApplicationInfo applicationInfo = new ApplicationInfo();
144         applicationInfo.uid = TEST_UID;  // non-zero
145         final PackageInfo systemPackageInfo = new PackageInfo();
146         systemPackageInfo.packageName = TEST_SYSTEM_PACKAGE_NAME;
147         when(mMockPackageManager.getPackageInfo(eq(TEST_SYSTEM_PACKAGE_NAME), anyInt()))
148                 .thenReturn(systemPackageInfo);
149         when(mMockPackageManager.getPackageInfo(eq("android"), anyInt()))
150                 .thenReturn(packageInfo);
151 
152         // Package has one channel by default.
153         when(mMockINotificationManager.getNumNotificationChannelsForPackage(
154                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(1);
155 
156         // Some test channels.
157         mNotificationChannel = new NotificationChannel(
158                 TEST_CHANNEL, TEST_CHANNEL_NAME, IMPORTANCE_LOW);
159         mDefaultNotificationChannel = new NotificationChannel(
160                 NotificationChannel.DEFAULT_CHANNEL_ID, TEST_CHANNEL_NAME,
161                 IMPORTANCE_LOW);
162         Notification notification = new Notification();
163         notification.extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, applicationInfo);
164         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
165                 notification, UserHandle.getUserHandleForUid(TEST_UID), null, 0);
166         mEntry = new NotificationEntryBuilder().setSbn(mSbn).build();
167         when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(false);
168         when(mAssistantFeedbackController.getInlineDescriptionResource(any()))
169                 .thenReturn(R.string.notification_channel_summary_automatic);
170     }
171 
172     @Test
testBindNotification_SetsTextApplicationName()173     public void testBindNotification_SetsTextApplicationName() throws Exception {
174         when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
175         mNotificationInfo.bindNotification(
176                 mMockPackageManager,
177                 mMockINotificationManager,
178                 mOnUserInteractionCallback,
179                 mChannelEditorDialogController,
180                 TEST_PACKAGE_NAME,
181                 mNotificationChannel,
182                 mEntry,
183                 null,
184                 null,
185                 mUiEventLogger,
186                 true,
187                 false,
188                 true,
189                 mAssistantFeedbackController,
190                 mMetricsLogger);
191         final TextView textView = mNotificationInfo.findViewById(R.id.pkg_name);
192         assertTrue(textView.getText().toString().contains("App Name"));
193         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
194     }
195 
196     @Test
testBindNotification_SetsPackageIcon()197     public void testBindNotification_SetsPackageIcon() throws Exception {
198         final Drawable iconDrawable = mock(Drawable.class);
199         when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
200                 .thenReturn(iconDrawable);
201         mNotificationInfo.bindNotification(
202                 mMockPackageManager,
203                 mMockINotificationManager,
204                 mOnUserInteractionCallback,
205                 mChannelEditorDialogController,
206                 TEST_PACKAGE_NAME,
207                 mNotificationChannel,
208                 mEntry,
209                 null,
210                 null,
211                 mUiEventLogger,
212                 true,
213                 false,
214                 true,
215                 mAssistantFeedbackController,
216                 mMetricsLogger);
217         final ImageView iconView = mNotificationInfo.findViewById(R.id.pkg_icon);
218         assertEquals(iconDrawable, iconView.getDrawable());
219     }
220 
221     @Test
testBindNotification_noDelegate()222     public void testBindNotification_noDelegate() throws Exception {
223         mNotificationInfo.bindNotification(
224                 mMockPackageManager,
225                 mMockINotificationManager,
226                 mOnUserInteractionCallback,
227                 mChannelEditorDialogController,
228                 TEST_PACKAGE_NAME,
229                 mNotificationChannel,
230                 mEntry,
231                 null,
232                 null,
233                 mUiEventLogger,
234                 true,
235                 false,
236                 true,
237                 mAssistantFeedbackController,
238                 mMetricsLogger);
239         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
240         assertEquals(GONE, nameView.getVisibility());
241     }
242 
243     @Test
testBindNotification_delegate()244     public void testBindNotification_delegate() throws Exception {
245         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, "other", 0, null, TEST_UID, 0,
246                 new Notification(), UserHandle.CURRENT, null, 0);
247         final ApplicationInfo applicationInfo = new ApplicationInfo();
248         applicationInfo.uid = 7;  // non-zero
249         when(mMockPackageManager.getApplicationInfo(eq("other"), anyInt())).thenReturn(
250                 applicationInfo);
251         when(mMockPackageManager.getApplicationLabel(any())).thenReturn("Other");
252 
253         NotificationEntry entry = new NotificationEntryBuilder().setSbn(mSbn).build();
254         mNotificationInfo.bindNotification(
255                 mMockPackageManager,
256                 mMockINotificationManager,
257                 mOnUserInteractionCallback,
258                 mChannelEditorDialogController,
259                 TEST_PACKAGE_NAME,
260                 mNotificationChannel,
261                 entry,
262                 null,
263                 null,
264                 mUiEventLogger,
265                 true,
266                 false,
267                 true,
268                 mAssistantFeedbackController,
269                 mMetricsLogger);
270         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
271         assertEquals(VISIBLE, nameView.getVisibility());
272         assertTrue(nameView.getText().toString().contains("Proxied"));
273     }
274 
275     @Test
testBindNotification_GroupNameHiddenIfNoGroup()276     public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
277         mNotificationInfo.bindNotification(
278                 mMockPackageManager,
279                 mMockINotificationManager,
280                 mOnUserInteractionCallback,
281                 mChannelEditorDialogController,
282                 TEST_PACKAGE_NAME,
283                 mNotificationChannel,
284                 mEntry,
285                 null,
286                 null,
287                 mUiEventLogger,
288                 true,
289                 false,
290                 true,
291                 mAssistantFeedbackController,
292                 mMetricsLogger);
293         final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
294         assertEquals(GONE, groupNameView.getVisibility());
295     }
296 
297     @Test
testBindNotification_SetsGroupNameIfNonNull()298     public void testBindNotification_SetsGroupNameIfNonNull() throws Exception {
299         mNotificationChannel.setGroup("test_group_id");
300         final NotificationChannelGroup notificationChannelGroup =
301                 new NotificationChannelGroup("test_group_id", "Test Group Name");
302         when(mMockINotificationManager.getNotificationChannelGroupForPackage(
303                 eq("test_group_id"), eq(TEST_PACKAGE_NAME), eq(TEST_UID)))
304                 .thenReturn(notificationChannelGroup);
305         mNotificationInfo.bindNotification(
306                 mMockPackageManager,
307                 mMockINotificationManager,
308                 mOnUserInteractionCallback,
309                 mChannelEditorDialogController,
310                 TEST_PACKAGE_NAME,
311                 mNotificationChannel,
312                 mEntry,
313                 null,
314                 null,
315                 mUiEventLogger,
316                 true,
317                 false,
318                 true,
319                 mAssistantFeedbackController,
320                 mMetricsLogger);
321         final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
322         assertEquals(View.VISIBLE, groupNameView.getVisibility());
323         assertEquals("Test Group Name", groupNameView.getText());
324     }
325 
326     @Test
testBindNotification_SetsTextChannelName()327     public void testBindNotification_SetsTextChannelName() throws Exception {
328         mNotificationInfo.bindNotification(
329                 mMockPackageManager,
330                 mMockINotificationManager,
331                 mOnUserInteractionCallback,
332                 mChannelEditorDialogController,
333                 TEST_PACKAGE_NAME,
334                 mNotificationChannel,
335                 mEntry,
336                 null,
337                 null,
338                 mUiEventLogger,
339                 true,
340                 false,
341                 true,
342                 mAssistantFeedbackController,
343                 mMetricsLogger);
344         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
345         assertEquals(TEST_CHANNEL_NAME, textView.getText());
346     }
347 
348     @Test
testBindNotification_DefaultChannelDoesNotUseChannelName()349     public void testBindNotification_DefaultChannelDoesNotUseChannelName() throws Exception {
350         mNotificationInfo.bindNotification(
351                 mMockPackageManager,
352                 mMockINotificationManager,
353                 mOnUserInteractionCallback,
354                 mChannelEditorDialogController,
355                 TEST_PACKAGE_NAME,
356                 mDefaultNotificationChannel,
357                 mEntry,
358                 null,
359                 null,
360                 mUiEventLogger,
361                 true,
362                 false,
363                 true,
364                 mAssistantFeedbackController,
365                 mMetricsLogger);
366         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
367         assertEquals(GONE, textView.getVisibility());
368     }
369 
370     @Test
testBindNotification_DefaultChannelUsesChannelNameIfMoreChannelsExist()371     public void testBindNotification_DefaultChannelUsesChannelNameIfMoreChannelsExist()
372             throws Exception {
373         // Package has more than one channel by default.
374         when(mMockINotificationManager.getNumNotificationChannelsForPackage(
375                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(10);
376         mNotificationInfo.bindNotification(
377                 mMockPackageManager,
378                 mMockINotificationManager,
379                 mOnUserInteractionCallback,
380                 mChannelEditorDialogController,
381                 TEST_PACKAGE_NAME,
382                 mDefaultNotificationChannel,
383                 mEntry,
384                 null,
385                 null,
386                 mUiEventLogger,
387                 true,
388                 false,
389                 true,
390                 mAssistantFeedbackController,
391                 mMetricsLogger);
392         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
393         assertEquals(VISIBLE, textView.getVisibility());
394     }
395 
396     @Test
testBindNotification_UnblockablePackageUsesChannelName()397     public void testBindNotification_UnblockablePackageUsesChannelName() throws Exception {
398         mNotificationInfo.bindNotification(
399                 mMockPackageManager,
400                 mMockINotificationManager,
401                 mOnUserInteractionCallback,
402                 mChannelEditorDialogController,
403                 TEST_PACKAGE_NAME,
404                 mNotificationChannel,
405                 mEntry,
406                 null,
407                 null,
408                 mUiEventLogger,
409                 true,
410                 true,
411                 true,
412                 mAssistantFeedbackController,
413                 mMetricsLogger);
414         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
415         assertEquals(VISIBLE, textView.getVisibility());
416     }
417 
418     @Test
testBindNotification_SetsOnClickListenerForSettings()419     public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
420         final CountDownLatch latch = new CountDownLatch(1);
421         mNotificationInfo.bindNotification(
422                 mMockPackageManager,
423                 mMockINotificationManager,
424                 mOnUserInteractionCallback,
425                 mChannelEditorDialogController,
426                 TEST_PACKAGE_NAME,
427                 mNotificationChannel,
428                 mEntry,
429                 (View v, NotificationChannel c, int appUid) -> {
430                     assertEquals(mNotificationChannel, c);
431                     latch.countDown();
432                 },
433                 null,
434                 mUiEventLogger,
435                 true,
436                 false,
437                 true,
438                 mAssistantFeedbackController,
439                 mMetricsLogger);
440 
441         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
442         settingsButton.performClick();
443         // Verify that listener was triggered.
444         assertEquals(0, latch.getCount());
445     }
446 
447     @Test
testBindNotification_SettingsButtonInvisibleWhenNoClickListener()448     public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() throws Exception {
449         mNotificationInfo.bindNotification(
450                 mMockPackageManager,
451                 mMockINotificationManager,
452                 mOnUserInteractionCallback,
453                 mChannelEditorDialogController,
454                 TEST_PACKAGE_NAME,
455                 mNotificationChannel,
456                 mEntry,
457                 null,
458                 null,
459                 mUiEventLogger,
460                 true,
461                 false,
462                 true,
463                 mAssistantFeedbackController,
464                 mMetricsLogger);
465         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
466         assertTrue(settingsButton.getVisibility() != View.VISIBLE);
467     }
468 
469     @Test
testBindNotification_SettingsButtonInvisibleWhenDeviceUnprovisioned()470     public void testBindNotification_SettingsButtonInvisibleWhenDeviceUnprovisioned()
471             throws Exception {
472         mNotificationInfo.bindNotification(
473                 mMockPackageManager,
474                 mMockINotificationManager,
475                 mOnUserInteractionCallback,
476                 mChannelEditorDialogController,
477                 TEST_PACKAGE_NAME,
478                 mNotificationChannel,
479                 mEntry,
480                 (View v, NotificationChannel c, int appUid) -> {
481                     assertEquals(mNotificationChannel, c);
482                 },
483                 null,
484                 mUiEventLogger,
485                 false,
486                 false,
487                 true,
488                 mAssistantFeedbackController,
489                 mMetricsLogger);
490         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
491         assertTrue(settingsButton.getVisibility() != View.VISIBLE);
492     }
493 
494     @Test
testBindNotification_SettingsButtonReappearsAfterSecondBind()495     public void testBindNotification_SettingsButtonReappearsAfterSecondBind() throws Exception {
496         mNotificationInfo.bindNotification(
497                 mMockPackageManager,
498                 mMockINotificationManager,
499                 mOnUserInteractionCallback,
500                 mChannelEditorDialogController,
501                 TEST_PACKAGE_NAME,
502                 mNotificationChannel,
503                 mEntry,
504                 null,
505                 null,
506                 mUiEventLogger,
507                 true,
508                 false,
509                 true,
510                 mAssistantFeedbackController,
511                 mMetricsLogger);
512         mNotificationInfo.bindNotification(
513                 mMockPackageManager,
514                 mMockINotificationManager,
515                 mOnUserInteractionCallback,
516                 mChannelEditorDialogController,
517                 TEST_PACKAGE_NAME,
518                 mNotificationChannel,
519                 mEntry,
520                 (View v, NotificationChannel c, int appUid) -> { },
521                 null,
522                 mUiEventLogger,
523                 true,
524                 false,
525                 true,
526                 mAssistantFeedbackController,
527                 mMetricsLogger);
528         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
529         assertEquals(View.VISIBLE, settingsButton.getVisibility());
530     }
531 
532     @Test
testBindNotification_whenAppUnblockable()533     public void testBindNotification_whenAppUnblockable() throws Exception {
534         mNotificationInfo.bindNotification(
535                 mMockPackageManager,
536                 mMockINotificationManager,
537                 mOnUserInteractionCallback,
538                 mChannelEditorDialogController,
539                 TEST_PACKAGE_NAME,
540                 mNotificationChannel,
541                 mEntry,
542                 null,
543                 null,
544                 mUiEventLogger,
545                 true,
546                 true,
547                 true,
548                 mAssistantFeedbackController,
549                 mMetricsLogger);
550         final TextView view = mNotificationInfo.findViewById(R.id.non_configurable_text);
551         assertEquals(View.VISIBLE, view.getVisibility());
552         assertEquals(mContext.getString(R.string.notification_unblockable_desc),
553                 view.getText());
554         assertEquals(GONE,
555                 mNotificationInfo.findViewById(R.id.interruptiveness_settings).getVisibility());
556     }
557 
558     @Test
testBindNotification_whenCurrentlyInCall()559     public void testBindNotification_whenCurrentlyInCall() throws Exception {
560         when(mMockINotificationManager.isInCall(anyString(), anyInt())).thenReturn(true);
561 
562         Person person = new Person.Builder()
563                 .setName("caller")
564                 .build();
565         Notification.Builder nb = new Notification.Builder(
566                 mContext, mNotificationChannel.getId())
567                 .setContentTitle("foo")
568                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
569                 .setStyle(Notification.CallStyle.forOngoingCall(
570                         person, mock(PendingIntent.class)))
571                 .setFullScreenIntent(mock(PendingIntent.class), true)
572                 .addAction(new Notification.Action.Builder(null, "test", null).build());
573 
574         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
575                 nb.build(), UserHandle.getUserHandleForUid(TEST_UID), null, 0);
576         mEntry.setSbn(mSbn);
577         mNotificationInfo.bindNotification(
578                 mMockPackageManager,
579                 mMockINotificationManager,
580                 mOnUserInteractionCallback,
581                 mChannelEditorDialogController,
582                 TEST_PACKAGE_NAME,
583                 mNotificationChannel,
584                 mEntry,
585                 null,
586                 null,
587                 mUiEventLogger,
588                 true,
589                 false,
590                 true,
591                 mAssistantFeedbackController,
592                 mMetricsLogger);
593         final TextView view = mNotificationInfo.findViewById(R.id.non_configurable_call_text);
594         assertEquals(View.VISIBLE, view.getVisibility());
595         assertEquals(mContext.getString(R.string.notification_unblockable_call_desc),
596                 view.getText());
597         assertEquals(GONE,
598                 mNotificationInfo.findViewById(R.id.interruptiveness_settings).getVisibility());
599         assertEquals(GONE,
600                 mNotificationInfo.findViewById(R.id.non_configurable_text).getVisibility());
601     }
602 
603     @Test
testBindNotification_whenCurrentlyInCall_notCall()604     public void testBindNotification_whenCurrentlyInCall_notCall() throws Exception {
605         when(mMockINotificationManager.isInCall(anyString(), anyInt())).thenReturn(true);
606 
607         Person person = new Person.Builder()
608                 .setName("caller")
609                 .build();
610         Notification.Builder nb = new Notification.Builder(
611                 mContext, mNotificationChannel.getId())
612                 .setContentTitle("foo")
613                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
614                 .setFullScreenIntent(mock(PendingIntent.class), true)
615                 .addAction(new Notification.Action.Builder(null, "test", null).build());
616 
617         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
618                 nb.build(), UserHandle.getUserHandleForUid(TEST_UID), null, 0);
619         mEntry.setSbn(mSbn);
620         mNotificationInfo.bindNotification(
621                 mMockPackageManager,
622                 mMockINotificationManager,
623                 mOnUserInteractionCallback,
624                 mChannelEditorDialogController,
625                 TEST_PACKAGE_NAME,
626                 mNotificationChannel,
627                 mEntry,
628                 null,
629                 null,
630                 mUiEventLogger,
631                 true,
632                 false,
633                 true,
634                 mAssistantFeedbackController,
635                 mMetricsLogger);
636         assertEquals(GONE,
637                 mNotificationInfo.findViewById(R.id.non_configurable_call_text).getVisibility());
638         assertEquals(VISIBLE,
639                 mNotificationInfo.findViewById(R.id.interruptiveness_settings).getVisibility());
640         assertEquals(GONE,
641                 mNotificationInfo.findViewById(R.id.non_configurable_text).getVisibility());
642     }
643 
644     @Test
testBindNotification_automaticIsVisible()645     public void testBindNotification_automaticIsVisible() throws Exception {
646         when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(true);
647         mNotificationInfo.bindNotification(
648                 mMockPackageManager,
649                 mMockINotificationManager,
650                 mOnUserInteractionCallback,
651                 mChannelEditorDialogController,
652                 TEST_PACKAGE_NAME,
653                 mNotificationChannel,
654                 mEntry,
655                 null,
656                 null,
657                 mUiEventLogger,
658                 true,
659                 false,
660                 true,
661                 mAssistantFeedbackController,
662                 mMetricsLogger);
663         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.automatic).getVisibility());
664         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.automatic_summary).getVisibility());
665     }
666 
667     @Test
testBindNotification_automaticIsGone()668     public void testBindNotification_automaticIsGone() throws Exception {
669         mNotificationInfo.bindNotification(
670                 mMockPackageManager,
671                 mMockINotificationManager,
672                 mOnUserInteractionCallback,
673                 mChannelEditorDialogController,
674                 TEST_PACKAGE_NAME,
675                 mNotificationChannel,
676                 mEntry,
677                 null,
678                 null,
679                 mUiEventLogger,
680                 true,
681                 false,
682                 true,
683                 mAssistantFeedbackController,
684                 mMetricsLogger);
685         assertEquals(GONE, mNotificationInfo.findViewById(R.id.automatic).getVisibility());
686         assertEquals(GONE, mNotificationInfo.findViewById(R.id.automatic_summary).getVisibility());
687     }
688 
689     @Test
testBindNotification_automaticIsSelected()690     public void testBindNotification_automaticIsSelected() throws Exception {
691         when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(true);
692         mNotificationChannel.unlockFields(USER_LOCKED_IMPORTANCE);
693         mNotificationInfo.bindNotification(
694                 mMockPackageManager,
695                 mMockINotificationManager,
696                 mOnUserInteractionCallback,
697                 mChannelEditorDialogController,
698                 TEST_PACKAGE_NAME,
699                 mNotificationChannel,
700                 mEntry,
701                 null,
702                 null,
703                 mUiEventLogger,
704                 true,
705                 false,
706                 true,
707                 mAssistantFeedbackController,
708                 mMetricsLogger);
709         assertTrue(mNotificationInfo.findViewById(R.id.automatic).isSelected());
710     }
711 
712     @Test
testBindNotification_alertIsSelected()713     public void testBindNotification_alertIsSelected() throws Exception {
714         mNotificationInfo.bindNotification(
715                 mMockPackageManager,
716                 mMockINotificationManager,
717                 mOnUserInteractionCallback,
718                 mChannelEditorDialogController,
719                 TEST_PACKAGE_NAME,
720                 mNotificationChannel,
721                 mEntry,
722                 null,
723                 null,
724                 mUiEventLogger,
725                 true,
726                 false,
727                 true,
728                 mAssistantFeedbackController,
729                 mMetricsLogger);
730         assertTrue(mNotificationInfo.findViewById(R.id.alert).isSelected());
731     }
732 
733     @Test
testBindNotification_silenceIsSelected()734     public void testBindNotification_silenceIsSelected() throws Exception {
735         mNotificationInfo.bindNotification(
736                 mMockPackageManager,
737                 mMockINotificationManager,
738                 mOnUserInteractionCallback,
739                 mChannelEditorDialogController,
740                 TEST_PACKAGE_NAME,
741                 mNotificationChannel,
742                 mEntry,
743                 null,
744                 null,
745                 mUiEventLogger,
746                 true,
747                 false,
748                 false,
749                 mAssistantFeedbackController,
750                 mMetricsLogger);
751         assertTrue(mNotificationInfo.findViewById(R.id.silence).isSelected());
752     }
753 
754     @Test
testBindNotification_DoesNotUpdateNotificationChannel()755     public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
756         mNotificationInfo.bindNotification(
757                 mMockPackageManager,
758                 mMockINotificationManager,
759                 mOnUserInteractionCallback,
760                 mChannelEditorDialogController,
761                 TEST_PACKAGE_NAME,
762                 mNotificationChannel,
763                 mEntry,
764                 null,
765                 null,
766                 mUiEventLogger,
767                 true,
768                 false,
769                 true,
770                 mAssistantFeedbackController,
771                 mMetricsLogger);
772         mTestableLooper.processAllMessages();
773         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
774                 anyString(), eq(TEST_UID), any());
775     }
776 
777     @Test
testBindNotification_LogsOpen()778     public void testBindNotification_LogsOpen() throws Exception {
779         mNotificationInfo.bindNotification(
780                 mMockPackageManager,
781                 mMockINotificationManager,
782                 mOnUserInteractionCallback,
783                 mChannelEditorDialogController,
784                 TEST_PACKAGE_NAME,
785                 mNotificationChannel,
786                 mEntry,
787                 null,
788                 null,
789                 mUiEventLogger,
790                 true,
791                 false,
792                 true,
793                 mAssistantFeedbackController,
794                 mMetricsLogger);
795         assertEquals(1, mUiEventLogger.numLogs());
796         assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
797                 mUiEventLogger.eventId(0));
798     }
799 
800     @Test
testDoesNotUpdateNotificationChannelAfterImportanceChanged()801     public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
802         mNotificationChannel.setImportance(IMPORTANCE_LOW);
803         mNotificationInfo.bindNotification(
804                 mMockPackageManager,
805                 mMockINotificationManager,
806                 mOnUserInteractionCallback,
807                 mChannelEditorDialogController,
808                 TEST_PACKAGE_NAME,
809                 mNotificationChannel,
810                 mEntry,
811                 null,
812                 null,
813                 mUiEventLogger,
814                 true,
815                 false,
816                 false,
817                 mAssistantFeedbackController,
818                 mMetricsLogger);
819 
820         mNotificationInfo.findViewById(R.id.alert).performClick();
821         mTestableLooper.processAllMessages();
822         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
823                 anyString(), eq(TEST_UID), any());
824     }
825 
826     @Test
testDoesNotUpdateNotificationChannelAfterImportanceChangedSilenced()827     public void testDoesNotUpdateNotificationChannelAfterImportanceChangedSilenced()
828             throws Exception {
829         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
830         mNotificationInfo.bindNotification(
831                 mMockPackageManager,
832                 mMockINotificationManager,
833                 mOnUserInteractionCallback,
834                 mChannelEditorDialogController,
835                 TEST_PACKAGE_NAME,
836                 mNotificationChannel,
837                 mEntry,
838                 null,
839                 null,
840                 mUiEventLogger,
841                 true,
842                 false,
843                 true,
844                 mAssistantFeedbackController,
845                 mMetricsLogger);
846 
847         mNotificationInfo.findViewById(R.id.silence).performClick();
848         mTestableLooper.processAllMessages();
849         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
850                 anyString(), eq(TEST_UID), any());
851     }
852 
853     @Test
testDoesNotUpdateNotificationChannelAfterImportanceChangedAutomatic()854     public void testDoesNotUpdateNotificationChannelAfterImportanceChangedAutomatic()
855             throws Exception {
856         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
857         mNotificationInfo.bindNotification(
858                 mMockPackageManager,
859                 mMockINotificationManager,
860                 mOnUserInteractionCallback,
861                 mChannelEditorDialogController,
862                 TEST_PACKAGE_NAME,
863                 mNotificationChannel,
864                 mEntry,
865                 null,
866                 null,
867                 mUiEventLogger,
868                 true,
869                 false,
870                 true,
871                 mAssistantFeedbackController,
872                 mMetricsLogger);
873 
874         mNotificationInfo.findViewById(R.id.automatic).performClick();
875         mTestableLooper.processAllMessages();
876         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
877                 anyString(), eq(TEST_UID), any());
878     }
879 
880     @Test
testHandleCloseControls_persistAutomatic()881     public void testHandleCloseControls_persistAutomatic()
882             throws Exception {
883         when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(true);
884         mNotificationChannel.unlockFields(USER_LOCKED_IMPORTANCE);
885         mNotificationInfo.bindNotification(
886                 mMockPackageManager,
887                 mMockINotificationManager,
888                 mOnUserInteractionCallback,
889                 mChannelEditorDialogController,
890                 TEST_PACKAGE_NAME,
891                 mNotificationChannel,
892                 mEntry,
893                 null,
894                 null,
895                 mUiEventLogger,
896                 true,
897                 false,
898                 true,
899                 mAssistantFeedbackController,
900                 mMetricsLogger);
901 
902         mNotificationInfo.handleCloseControls(true, false);
903         mTestableLooper.processAllMessages();
904         verify(mMockINotificationManager, times(1)).unlockNotificationChannel(
905                 anyString(), eq(TEST_UID), any());
906     }
907 
908     @Test
testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()909     public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
910             throws Exception {
911         int originalImportance = mNotificationChannel.getImportance();
912         mNotificationInfo.bindNotification(
913                 mMockPackageManager,
914                 mMockINotificationManager,
915                 mOnUserInteractionCallback,
916                 mChannelEditorDialogController,
917                 TEST_PACKAGE_NAME,
918                 mNotificationChannel,
919                 mEntry,
920                 null,
921                 null,
922                 mUiEventLogger,
923                 true,
924                 false,
925                 true,
926                 mAssistantFeedbackController,
927                 mMetricsLogger);
928 
929         mNotificationInfo.handleCloseControls(true, false);
930         mTestableLooper.processAllMessages();
931         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
932                 anyString(), eq(TEST_UID), any());
933         assertEquals(originalImportance, mNotificationChannel.getImportance());
934 
935         assertEquals(2, mUiEventLogger.numLogs());
936         assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
937                 mUiEventLogger.eventId(0));
938         // The SAVE_IMPORTANCE event is logged whenever importance is saved, even if unchanged.
939         assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_SAVE_IMPORTANCE.getId(),
940                 mUiEventLogger.eventId(1));
941     }
942 
943     @Test
testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnspecified()944     public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnspecified()
945             throws Exception {
946         mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
947         mNotificationInfo.bindNotification(
948                 mMockPackageManager,
949                 mMockINotificationManager,
950                 mOnUserInteractionCallback,
951                 mChannelEditorDialogController,
952                 TEST_PACKAGE_NAME,
953                 mNotificationChannel,
954                 mEntry,
955                 null,
956                 null,
957                 mUiEventLogger,
958                 true,
959                 false,
960                 true,
961                 mAssistantFeedbackController,
962                 mMetricsLogger);
963 
964         mNotificationInfo.handleCloseControls(true, false);
965 
966         mTestableLooper.processAllMessages();
967         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
968                 anyString(), eq(TEST_UID), any());
969         assertEquals(IMPORTANCE_UNSPECIFIED, mNotificationChannel.getImportance());
970     }
971 
972     @Test
testSilenceCallsUpdateNotificationChannel()973     public void testSilenceCallsUpdateNotificationChannel() throws Exception {
974         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
975         mNotificationInfo.bindNotification(
976                 mMockPackageManager,
977                 mMockINotificationManager,
978                 mOnUserInteractionCallback,
979                 mChannelEditorDialogController,
980                 TEST_PACKAGE_NAME,
981                 mNotificationChannel,
982                 mEntry,
983                 null,
984                 null,
985                 mUiEventLogger,
986                 true,
987                 false,
988                 true,
989                 mAssistantFeedbackController,
990                 mMetricsLogger);
991 
992         mNotificationInfo.findViewById(R.id.silence).performClick();
993         mNotificationInfo.findViewById(R.id.done).performClick();
994         mNotificationInfo.handleCloseControls(true, false);
995 
996         mTestableLooper.processAllMessages();
997         ArgumentCaptor<NotificationChannel> updated =
998                 ArgumentCaptor.forClass(NotificationChannel.class);
999         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
1000                 anyString(), eq(TEST_UID), updated.capture());
1001         assertTrue((updated.getValue().getUserLockedFields()
1002                 & USER_LOCKED_IMPORTANCE) != 0);
1003         assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance());
1004 
1005         assertEquals(2, mUiEventLogger.numLogs());
1006         assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
1007                 mUiEventLogger.eventId(0));
1008         assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_SAVE_IMPORTANCE.getId(),
1009                 mUiEventLogger.eventId(1));
1010         assertFalse(mNotificationInfo.shouldBeSavedOnClose());
1011     }
1012 
1013     @Test
testUnSilenceCallsUpdateNotificationChannel()1014     public void testUnSilenceCallsUpdateNotificationChannel() throws Exception {
1015         mNotificationChannel.setImportance(IMPORTANCE_LOW);
1016         mNotificationInfo.bindNotification(
1017                 mMockPackageManager,
1018                 mMockINotificationManager,
1019                 mOnUserInteractionCallback,
1020                 mChannelEditorDialogController,
1021                 TEST_PACKAGE_NAME,
1022                 mNotificationChannel,
1023                 mEntry,
1024                 null,
1025                 null,
1026                 mUiEventLogger,
1027                 true,
1028                 false,
1029                 false,
1030                 mAssistantFeedbackController,
1031                 mMetricsLogger);
1032 
1033         mNotificationInfo.findViewById(R.id.alert).performClick();
1034         mNotificationInfo.findViewById(R.id.done).performClick();
1035         mNotificationInfo.handleCloseControls(true, false);
1036 
1037         mTestableLooper.processAllMessages();
1038         ArgumentCaptor<NotificationChannel> updated =
1039                 ArgumentCaptor.forClass(NotificationChannel.class);
1040         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
1041                 anyString(), eq(TEST_UID), updated.capture());
1042         assertTrue((updated.getValue().getUserLockedFields()
1043                 & USER_LOCKED_IMPORTANCE) != 0);
1044         assertEquals(IMPORTANCE_DEFAULT, updated.getValue().getImportance());
1045         assertFalse(mNotificationInfo.shouldBeSavedOnClose());
1046     }
1047 
1048     @Test
testAutomaticUnlocksUserImportance()1049     public void testAutomaticUnlocksUserImportance() throws Exception {
1050         when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(true);
1051         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
1052         mNotificationChannel.lockFields(USER_LOCKED_IMPORTANCE);
1053         mNotificationInfo.bindNotification(
1054                 mMockPackageManager,
1055                 mMockINotificationManager,
1056                 mOnUserInteractionCallback,
1057                 mChannelEditorDialogController,
1058                 TEST_PACKAGE_NAME,
1059                 mNotificationChannel,
1060                 mEntry,
1061                 null,
1062                 null,
1063                 mUiEventLogger,
1064                 true,
1065                 false,
1066                 true,
1067                 mAssistantFeedbackController,
1068                 mMetricsLogger);
1069 
1070         mNotificationInfo.findViewById(R.id.automatic).performClick();
1071         mNotificationInfo.findViewById(R.id.done).performClick();
1072         mNotificationInfo.handleCloseControls(true, false);
1073 
1074         mTestableLooper.processAllMessages();
1075         verify(mMockINotificationManager, times(1)).unlockNotificationChannel(
1076                 anyString(), eq(TEST_UID), any());
1077         assertEquals(IMPORTANCE_DEFAULT, mNotificationChannel.getImportance());
1078         assertFalse(mNotificationInfo.shouldBeSavedOnClose());
1079     }
1080 
1081     @Test
testSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()1082     public void testSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()
1083             throws Exception {
1084         mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
1085         mNotificationInfo.bindNotification(
1086                 mMockPackageManager,
1087                 mMockINotificationManager,
1088                 mOnUserInteractionCallback,
1089                 mChannelEditorDialogController,
1090                 TEST_PACKAGE_NAME,
1091                 mNotificationChannel,
1092                 mEntry,
1093                 null,
1094                 null,
1095                 mUiEventLogger,
1096                 true,
1097                 false,
1098                 true,
1099                 mAssistantFeedbackController,
1100                 mMetricsLogger);
1101 
1102         mNotificationInfo.findViewById(R.id.silence).performClick();
1103         mNotificationInfo.findViewById(R.id.done).performClick();
1104         mNotificationInfo.handleCloseControls(true, false);
1105 
1106         mTestableLooper.processAllMessages();
1107         ArgumentCaptor<NotificationChannel> updated =
1108                 ArgumentCaptor.forClass(NotificationChannel.class);
1109         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
1110                 anyString(), eq(TEST_UID), updated.capture());
1111         assertTrue((updated.getValue().getUserLockedFields()
1112                 & USER_LOCKED_IMPORTANCE) != 0);
1113         assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance());
1114         assertFalse(mNotificationInfo.shouldBeSavedOnClose());
1115     }
1116 
1117     @Test
testSilenceCallsUpdateNotificationChannel_channelImportanceMin()1118     public void testSilenceCallsUpdateNotificationChannel_channelImportanceMin()
1119             throws Exception {
1120         mNotificationChannel.setImportance(IMPORTANCE_MIN);
1121         mNotificationInfo.bindNotification(
1122                 mMockPackageManager,
1123                 mMockINotificationManager,
1124                 mOnUserInteractionCallback,
1125                 mChannelEditorDialogController,
1126                 TEST_PACKAGE_NAME,
1127                 mNotificationChannel,
1128                 mEntry,
1129                 null,
1130                 null,
1131                 mUiEventLogger,
1132                 true,
1133                 false,
1134                 false,
1135                 mAssistantFeedbackController,
1136                 mMetricsLogger);
1137 
1138         assertEquals(mContext.getString(R.string.inline_done_button),
1139                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
1140         mNotificationInfo.findViewById(R.id.silence).performClick();
1141         assertEquals(mContext.getString(R.string.inline_done_button),
1142                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
1143         mNotificationInfo.findViewById(R.id.done).performClick();
1144         mNotificationInfo.handleCloseControls(true, false);
1145 
1146         mTestableLooper.processAllMessages();
1147         ArgumentCaptor<NotificationChannel> updated =
1148                 ArgumentCaptor.forClass(NotificationChannel.class);
1149         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
1150                 anyString(), eq(TEST_UID), updated.capture());
1151         assertTrue((updated.getValue().getUserLockedFields() & USER_LOCKED_IMPORTANCE) != 0);
1152         assertEquals(IMPORTANCE_MIN, updated.getValue().getImportance());
1153         assertFalse(mNotificationInfo.shouldBeSavedOnClose());
1154     }
1155 
1156     @Test
testSilence_closeGutsThenTryToSave()1157     public void testSilence_closeGutsThenTryToSave() throws RemoteException {
1158         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
1159         mNotificationInfo.bindNotification(
1160                 mMockPackageManager,
1161                 mMockINotificationManager,
1162                 mOnUserInteractionCallback,
1163                 mChannelEditorDialogController,
1164                 TEST_PACKAGE_NAME,
1165                 mNotificationChannel,
1166                 mEntry,
1167                 null,
1168                 null,
1169                 mUiEventLogger,
1170                 true,
1171                 false,
1172                 false,
1173                 mAssistantFeedbackController,
1174                 mMetricsLogger);
1175 
1176         mNotificationInfo.findViewById(R.id.silence).performClick();
1177         mNotificationInfo.handleCloseControls(false, false);
1178         mNotificationInfo.handleCloseControls(true, false);
1179 
1180         mTestableLooper.processAllMessages();
1181 
1182         assertEquals(IMPORTANCE_DEFAULT, mNotificationChannel.getImportance());
1183         assertFalse(mNotificationInfo.shouldBeSavedOnClose());
1184     }
1185 
1186     @Test
testAlertCallsUpdateNotificationChannel_channelImportanceMin()1187     public void testAlertCallsUpdateNotificationChannel_channelImportanceMin()
1188             throws Exception {
1189         mNotificationChannel.setImportance(IMPORTANCE_MIN);
1190         mNotificationInfo.bindNotification(
1191                 mMockPackageManager,
1192                 mMockINotificationManager,
1193                 mOnUserInteractionCallback,
1194                 mChannelEditorDialogController,
1195                 TEST_PACKAGE_NAME,
1196                 mNotificationChannel,
1197                 mEntry,
1198                 null,
1199                 null,
1200                 mUiEventLogger,
1201                 true,
1202                 false,
1203                 false,
1204                 mAssistantFeedbackController,
1205                 mMetricsLogger);
1206 
1207         assertEquals(mContext.getString(R.string.inline_done_button),
1208                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
1209         mNotificationInfo.findViewById(R.id.alert).performClick();
1210         assertEquals(mContext.getString(R.string.inline_ok_button),
1211                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
1212         mNotificationInfo.findViewById(R.id.done).performClick();
1213         mNotificationInfo.handleCloseControls(true, false);
1214 
1215         mTestableLooper.processAllMessages();
1216         ArgumentCaptor<NotificationChannel> updated =
1217                 ArgumentCaptor.forClass(NotificationChannel.class);
1218         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
1219                 anyString(), eq(TEST_UID), updated.capture());
1220         assertTrue((updated.getValue().getUserLockedFields() & USER_LOCKED_IMPORTANCE) != 0);
1221         assertEquals(IMPORTANCE_DEFAULT, updated.getValue().getImportance());
1222         assertFalse(mNotificationInfo.shouldBeSavedOnClose());
1223     }
1224 
1225     @Test
testAdjustImportanceTemporarilyAllowsReordering()1226     public void testAdjustImportanceTemporarilyAllowsReordering() throws Exception {
1227         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
1228         mNotificationInfo.bindNotification(
1229                 mMockPackageManager,
1230                 mMockINotificationManager,
1231                 mOnUserInteractionCallback,
1232                 mChannelEditorDialogController,
1233                 TEST_PACKAGE_NAME,
1234                 mNotificationChannel,
1235                 mEntry,
1236                 null,
1237                 null,
1238                 mUiEventLogger,
1239                 true,
1240                 false,
1241                 true,
1242                 mAssistantFeedbackController,
1243                 mMetricsLogger);
1244 
1245         mNotificationInfo.findViewById(R.id.silence).performClick();
1246         mNotificationInfo.findViewById(R.id.done).performClick();
1247         mNotificationInfo.handleCloseControls(true, false);
1248 
1249         verify(mOnUserInteractionCallback).onImportanceChanged(mEntry);
1250         assertFalse(mNotificationInfo.shouldBeSavedOnClose());
1251     }
1252 
1253     @Test
testDoneText()1254     public void testDoneText()
1255             throws Exception {
1256         mNotificationChannel.setImportance(IMPORTANCE_LOW);
1257         mNotificationInfo.bindNotification(
1258                 mMockPackageManager,
1259                 mMockINotificationManager,
1260                 mOnUserInteractionCallback,
1261                 mChannelEditorDialogController,
1262                 TEST_PACKAGE_NAME,
1263                 mNotificationChannel,
1264                 mEntry,
1265                 null,
1266                 null,
1267                 mUiEventLogger,
1268                 true,
1269                 false,
1270                 false,
1271                 mAssistantFeedbackController,
1272                 mMetricsLogger);
1273 
1274         assertEquals(mContext.getString(R.string.inline_done_button),
1275                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
1276         mNotificationInfo.findViewById(R.id.alert).performClick();
1277         assertEquals(mContext.getString(R.string.inline_ok_button),
1278                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
1279         mNotificationInfo.findViewById(R.id.silence).performClick();
1280         assertEquals(mContext.getString(R.string.inline_done_button),
1281                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
1282     }
1283 
1284     @Test
testUnSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()1285     public void testUnSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()
1286             throws Exception {
1287         mNotificationChannel.setImportance(IMPORTANCE_LOW);
1288         mNotificationInfo.bindNotification(
1289                 mMockPackageManager,
1290                 mMockINotificationManager,
1291                 mOnUserInteractionCallback,
1292                 mChannelEditorDialogController,
1293                 TEST_PACKAGE_NAME,
1294                 mNotificationChannel,
1295                 mEntry,
1296                 null,
1297                 null,
1298                 mUiEventLogger,
1299                 true,
1300                 false,
1301                 false,
1302                 mAssistantFeedbackController,
1303                 mMetricsLogger);
1304 
1305         mNotificationInfo.findViewById(R.id.alert).performClick();
1306         mNotificationInfo.findViewById(R.id.done).performClick();
1307         mNotificationInfo.handleCloseControls(true, false);
1308 
1309         mTestableLooper.processAllMessages();
1310         ArgumentCaptor<NotificationChannel> updated =
1311                 ArgumentCaptor.forClass(NotificationChannel.class);
1312         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
1313                 anyString(), eq(TEST_UID), updated.capture());
1314         assertTrue((updated.getValue().getUserLockedFields()
1315                 & USER_LOCKED_IMPORTANCE) != 0);
1316         assertEquals(IMPORTANCE_DEFAULT, updated.getValue().getImportance());
1317         assertFalse(mNotificationInfo.shouldBeSavedOnClose());
1318     }
1319 
1320     @Test
testCloseControlsDoesNotUpdateIfSaveIsFalse()1321     public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
1322         mNotificationChannel.setImportance(IMPORTANCE_LOW);
1323         mNotificationInfo.bindNotification(
1324                 mMockPackageManager,
1325                 mMockINotificationManager,
1326                 mOnUserInteractionCallback,
1327                 mChannelEditorDialogController,
1328                 TEST_PACKAGE_NAME,
1329                 mNotificationChannel,
1330                 mEntry,
1331                 null,
1332                 null,
1333                 mUiEventLogger,
1334                 true,
1335                 false,
1336                 false,
1337                 mAssistantFeedbackController,
1338                 mMetricsLogger);
1339 
1340         mNotificationInfo.findViewById(R.id.alert).performClick();
1341         mNotificationInfo.findViewById(R.id.done).performClick();
1342         mNotificationInfo.handleCloseControls(false, false);
1343 
1344         mTestableLooper.processAllMessages();
1345         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
1346                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
1347 
1348         assertEquals(1, mUiEventLogger.numLogs());
1349         assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
1350                 mUiEventLogger.eventId(0));
1351     }
1352 
1353     @Test
testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback()1354     public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception {
1355         mNotificationChannel.setImportance(IMPORTANCE_LOW);
1356         mNotificationInfo.bindNotification(
1357                 mMockPackageManager,
1358                 mMockINotificationManager,
1359                 mOnUserInteractionCallback,
1360                 mChannelEditorDialogController,
1361                 TEST_PACKAGE_NAME,
1362                 mNotificationChannel,
1363                 mEntry,
1364                 null,
1365                 null,
1366                 mUiEventLogger,
1367                 true,
1368                 false,
1369                 false,
1370                 mAssistantFeedbackController,
1371                 mMetricsLogger);
1372 
1373         mNotificationInfo.findViewById(R.id.alert).performClick();
1374         mNotificationInfo.findViewById(R.id.done).performClick();
1375         mTestableLooper.processAllMessages();
1376         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
1377                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
1378 
1379         mNotificationInfo.handleCloseControls(true, false);
1380 
1381         mTestableLooper.processAllMessages();
1382         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
1383                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
1384     }
1385 
1386     @Test
testCloseControls_withoutHittingApply()1387     public void testCloseControls_withoutHittingApply() throws Exception {
1388         mNotificationChannel.setImportance(IMPORTANCE_LOW);
1389         mNotificationInfo.bindNotification(
1390                 mMockPackageManager,
1391                 mMockINotificationManager,
1392                 mOnUserInteractionCallback,
1393                 mChannelEditorDialogController,
1394                 TEST_PACKAGE_NAME,
1395                 mNotificationChannel,
1396                 mEntry,
1397                 null,
1398                 null,
1399                 mUiEventLogger,
1400                 true,
1401                 false,
1402                 false,
1403                 mAssistantFeedbackController,
1404                 mMetricsLogger);
1405 
1406         mNotificationInfo.findViewById(R.id.alert).performClick();
1407 
1408         assertFalse(mNotificationInfo.shouldBeSavedOnClose());
1409     }
1410 
1411     @Test
testWillBeRemovedReturnsFalse()1412     public void testWillBeRemovedReturnsFalse() throws Exception {
1413         assertFalse(mNotificationInfo.willBeRemoved());
1414 
1415         mNotificationInfo.bindNotification(
1416                 mMockPackageManager,
1417                 mMockINotificationManager,
1418                 mOnUserInteractionCallback,
1419                 mChannelEditorDialogController,
1420                 TEST_PACKAGE_NAME,
1421                 mNotificationChannel,
1422                 mEntry,
1423                 null,
1424                 null,
1425                 mUiEventLogger,
1426                 true,
1427                 false,
1428                 false,
1429                 mAssistantFeedbackController,
1430                 mMetricsLogger);
1431 
1432         assertFalse(mNotificationInfo.willBeRemoved());
1433     }
1434 }
1435