Home | History | Annotate | Download | only in notification
      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.server.notification;
     18 
     19 import static android.app.NotificationManager.IMPORTANCE_HIGH;
     20 import static android.app.NotificationManager.IMPORTANCE_LOW;
     21 import static android.app.NotificationManager.IMPORTANCE_NONE;
     22 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
     23 import static android.content.pm.PackageManager.PERMISSION_DENIED;
     24 
     25 import static junit.framework.Assert.assertEquals;
     26 import static junit.framework.Assert.assertFalse;
     27 import static junit.framework.Assert.assertNotNull;
     28 import static junit.framework.Assert.assertNull;
     29 import static junit.framework.Assert.assertTrue;
     30 import static junit.framework.Assert.fail;
     31 
     32 import static org.mockito.Matchers.anyBoolean;
     33 import static org.mockito.Matchers.anyLong;
     34 import static org.mockito.Matchers.anyString;
     35 import static org.mockito.Matchers.eq;
     36 import static org.mockito.Mockito.any;
     37 import static org.mockito.Mockito.anyInt;
     38 import static org.mockito.Mockito.doAnswer;
     39 import static org.mockito.Mockito.mock;
     40 import static org.mockito.Mockito.never;
     41 import static org.mockito.Mockito.reset;
     42 import static org.mockito.Mockito.spy;
     43 import static org.mockito.Mockito.times;
     44 import static org.mockito.Mockito.verify;
     45 import static org.mockito.Mockito.when;
     46 
     47 import android.app.ActivityManager;
     48 import android.app.INotificationManager;
     49 import android.app.Notification;
     50 import android.app.NotificationChannel;
     51 import android.app.NotificationChannelGroup;
     52 import android.app.NotificationManager;
     53 import android.companion.ICompanionDeviceManager;
     54 import android.content.ComponentName;
     55 import android.content.Context;
     56 import android.content.Intent;
     57 import android.content.pm.ApplicationInfo;
     58 import android.content.pm.IPackageManager;
     59 import android.content.pm.PackageManager;
     60 import android.content.pm.ParceledListSlice;
     61 import android.graphics.Color;
     62 import android.media.AudioManager;
     63 import android.os.Binder;
     64 import android.os.Build;
     65 import android.os.Process;
     66 import android.os.UserHandle;
     67 import android.provider.Settings.Secure;
     68 import android.service.notification.NotificationListenerService;
     69 import android.service.notification.StatusBarNotification;
     70 import android.test.suitebuilder.annotation.SmallTest;
     71 import android.testing.AndroidTestingRunner;
     72 import android.testing.TestableContext;
     73 import android.testing.TestableLooper;
     74 import android.testing.TestableLooper.RunWithLooper;
     75 import android.util.ArrayMap;
     76 import android.util.AtomicFile;
     77 
     78 import com.android.server.lights.Light;
     79 import com.android.server.lights.LightsManager;
     80 import com.android.server.notification.NotificationManagerService.NotificationAssistants;
     81 import com.android.server.notification.NotificationManagerService.NotificationListeners;
     82 
     83 import org.junit.After;
     84 import org.junit.Before;
     85 import org.junit.Test;
     86 import org.junit.runner.RunWith;
     87 import org.mockito.Mock;
     88 import org.mockito.MockitoAnnotations;
     89 import org.mockito.stubbing.Answer;
     90 
     91 import java.io.BufferedInputStream;
     92 import java.io.ByteArrayInputStream;
     93 import java.io.File;
     94 import java.io.FileInputStream;
     95 import java.io.FileOutputStream;
     96 import java.util.ArrayList;
     97 import java.util.Arrays;
     98 import java.util.List;
     99 import java.util.Map;
    100 
    101 @SmallTest
    102 @RunWith(AndroidTestingRunner.class)
    103 @RunWithLooper
    104 public class NotificationManagerServiceTest extends NotificationTestCase {
    105     private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
    106     private final int mUid = Binder.getCallingUid();
    107     private NotificationManagerService mNotificationManagerService;
    108     private INotificationManager mBinderService;
    109     private NotificationManagerInternal mInternalService;
    110     @Mock
    111     private IPackageManager mPackageManager;
    112     @Mock
    113     private PackageManager mPackageManagerClient;
    114     private TestableContext mContext = spy(getContext());
    115     private final String PKG = mContext.getPackageName();
    116     private TestableLooper mTestableLooper;
    117     @Mock
    118     private RankingHelper mRankingHelper;
    119     AtomicFile mPolicyFile;
    120     File mFile;
    121     @Mock
    122     private NotificationUsageStats mUsageStats;
    123     @Mock
    124     private AudioManager mAudioManager;
    125     @Mock
    126     ActivityManager mActivityManager;
    127     NotificationManagerService.WorkerHandler mHandler;
    128 
    129     private NotificationChannel mTestNotificationChannel = new NotificationChannel(
    130             TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
    131     @Mock
    132     private NotificationListeners mListeners;
    133     @Mock private NotificationAssistants mAssistants;
    134     @Mock private ConditionProviders mConditionProviders;
    135     private ManagedServices.ManagedServiceInfo mListener;
    136     @Mock private ICompanionDeviceManager mCompanionMgr;
    137     @Mock SnoozeHelper mSnoozeHelper;
    138     @Mock GroupHelper mGroupHelper;
    139 
    140     // Use a Testable subclass so we can simulate calls from the system without failing.
    141     private static class TestableNotificationManagerService extends NotificationManagerService {
    142         public TestableNotificationManagerService(Context context) { super(context); }
    143 
    144         @Override
    145         protected boolean isCallingUidSystem() {
    146             return true;
    147         }
    148 
    149         @Override
    150         protected boolean isCallerSystemOrPhone() {
    151             return true;
    152         }
    153 
    154         @Override
    155         protected ICompanionDeviceManager getCompanionManager() {
    156             return null;
    157         }
    158     }
    159 
    160     @Before
    161     public void setUp() throws Exception {
    162         MockitoAnnotations.initMocks(this);
    163 
    164         // most tests assume badging is enabled
    165         Secure.putIntForUser(getContext().getContentResolver(),
    166                 Secure.NOTIFICATION_BADGING, 1,
    167                 UserHandle.getUserHandleForUid(mUid).getIdentifier());
    168 
    169         mNotificationManagerService = new TestableNotificationManagerService(mContext);
    170 
    171         // Use this testable looper.
    172         mTestableLooper = TestableLooper.get(this);
    173         mHandler = mNotificationManagerService.new WorkerHandler(mTestableLooper.getLooper());
    174         // MockPackageManager - default returns ApplicationInfo with matching calling UID
    175         mContext.setMockPackageManager(mPackageManagerClient);
    176         final ApplicationInfo applicationInfo = new ApplicationInfo();
    177         applicationInfo.uid = mUid;
    178         when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
    179                 .thenReturn(applicationInfo);
    180         when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
    181                 .thenReturn(applicationInfo);
    182         when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid);
    183         final LightsManager mockLightsManager = mock(LightsManager.class);
    184         when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
    185         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
    186 
    187         // write to a test file; the system file isn't readable from tests
    188         mFile = new File(mContext.getCacheDir(), "test.xml");
    189         mFile.createNewFile();
    190         final String preupgradeXml = "<notification-policy></notification-policy>";
    191         mPolicyFile = new AtomicFile(mFile);
    192         FileOutputStream fos = mPolicyFile.startWrite();
    193         fos.write(preupgradeXml.getBytes());
    194         mPolicyFile.finishWrite(fos);
    195         FileInputStream fStream = new FileInputStream(mFile);
    196 
    197         // Setup managed services
    198         mListener = mListeners.new ManagedServiceInfo(
    199                 null, new ComponentName(PKG, "test_class"), mUid, true, null, 0);
    200         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
    201         ManagedServices.Config listenerConfig = new ManagedServices.Config();
    202         listenerConfig.xmlTag = NotificationListeners.TAG_ENABLED_NOTIFICATION_LISTENERS;
    203         when(mListeners.getConfig()).thenReturn(listenerConfig);
    204         ManagedServices.Config assistantConfig = new ManagedServices.Config();
    205         assistantConfig.xmlTag = NotificationAssistants.TAG_ENABLED_NOTIFICATION_ASSISTANTS;
    206         when(mAssistants.getConfig()).thenReturn(assistantConfig);
    207         ManagedServices.Config dndConfig = new ManagedServices.Config();
    208         dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS;
    209         when(mConditionProviders.getConfig()).thenReturn(dndConfig);
    210 
    211         try {
    212             mNotificationManagerService.init(mTestableLooper.getLooper(),
    213                     mPackageManager, mPackageManagerClient, mockLightsManager,
    214                     mListeners, mAssistants, mConditionProviders,
    215                     mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
    216                     mGroupHelper);
    217         } catch (SecurityException e) {
    218             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
    219                 throw e;
    220             }
    221         }
    222         mNotificationManagerService.setAudioManager(mAudioManager);
    223 
    224         // Tests call directly into the Binder.
    225         mBinderService = mNotificationManagerService.getBinderService();
    226         mInternalService = mNotificationManagerService.getInternalService();
    227 
    228         mBinderService.createNotificationChannels(
    229                 PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel)));
    230         assertNotNull(mBinderService.getNotificationChannel(PKG, TEST_CHANNEL_ID));
    231     }
    232 
    233     @After
    234     public void tearDown() throws Exception {
    235         mFile.delete();
    236     }
    237 
    238     public void waitForIdle() throws Exception {
    239         mTestableLooper.processAllMessages();
    240     }
    241 
    242     private NotificationRecord generateNotificationRecord(NotificationChannel channel, int id,
    243             String groupKey, boolean isSummary) {
    244         Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
    245                 .setContentTitle("foo")
    246                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
    247                 .setGroup(groupKey)
    248                 .setGroupSummary(isSummary);
    249 
    250         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
    251                 nb.build(), new UserHandle(mUid), null, 0);
    252         return new NotificationRecord(mContext, sbn, channel);
    253     }
    254 
    255     private NotificationRecord generateNotificationRecord(NotificationChannel channel) {
    256         return generateNotificationRecord(channel, null);
    257     }
    258 
    259     private NotificationRecord generateNotificationRecord(NotificationChannel channel,
    260             Notification.TvExtender extender) {
    261         if (channel == null) {
    262             channel = mTestNotificationChannel;
    263         }
    264         Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
    265                 .setContentTitle("foo")
    266                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
    267         if (extender != null) {
    268             nb.extend(extender);
    269         }
    270         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
    271                 nb.build(), new UserHandle(mUid), null, 0);
    272         return new NotificationRecord(mContext, sbn, channel);
    273     }
    274 
    275     private Map<String, Answer> getSignalExtractorSideEffects() {
    276         Map<String, Answer> answers = new ArrayMap<>();
    277 
    278         answers.put("override group key", invocationOnMock -> {
    279             ((NotificationRecord) invocationOnMock.getArguments()[0])
    280                     .setOverrideGroupKey("bananas");
    281             return null;
    282         });
    283         answers.put("override people", invocationOnMock -> {
    284             ((NotificationRecord) invocationOnMock.getArguments()[0])
    285                     .setPeopleOverride(new ArrayList<>());
    286             return null;
    287         });
    288         answers.put("snooze criteria", invocationOnMock -> {
    289             ((NotificationRecord) invocationOnMock.getArguments()[0])
    290                     .setSnoozeCriteria(new ArrayList<>());
    291             return null;
    292         });
    293         answers.put("notification channel", invocationOnMock -> {
    294             ((NotificationRecord) invocationOnMock.getArguments()[0])
    295                     .updateNotificationChannel(new NotificationChannel("a", "", IMPORTANCE_LOW));
    296             return null;
    297         });
    298         answers.put("badging", invocationOnMock -> {
    299             NotificationRecord r = (NotificationRecord) invocationOnMock.getArguments()[0];
    300             r.setShowBadge(!r.canShowBadge());
    301             return null;
    302         });
    303         answers.put("package visibility", invocationOnMock -> {
    304             ((NotificationRecord) invocationOnMock.getArguments()[0]).setPackageVisibilityOverride(
    305                     Notification.VISIBILITY_SECRET);
    306             return null;
    307         });
    308 
    309         return answers;
    310     }
    311 
    312     @Test
    313     public void testCreateNotificationChannels_SingleChannel() throws Exception {
    314         final NotificationChannel channel =
    315                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
    316         mBinderService.createNotificationChannels(PKG,
    317                 new ParceledListSlice(Arrays.asList(channel)));
    318         final NotificationChannel createdChannel =
    319                 mBinderService.getNotificationChannel(PKG, "id");
    320         assertTrue(createdChannel != null);
    321     }
    322 
    323     @Test
    324     public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception {
    325         try {
    326             mBinderService.createNotificationChannels(PKG,
    327                     new ParceledListSlice(Arrays.asList(null)));
    328             fail("Exception should be thrown immediately.");
    329         } catch (NullPointerException e) {
    330             // pass
    331         }
    332     }
    333 
    334     @Test
    335     public void testCreateNotificationChannels_TwoChannels() throws Exception {
    336         final NotificationChannel channel1 =
    337                 new NotificationChannel("id1", "name", NotificationManager.IMPORTANCE_DEFAULT);
    338         final NotificationChannel channel2 =
    339                 new NotificationChannel("id2", "name", NotificationManager.IMPORTANCE_DEFAULT);
    340         mBinderService.createNotificationChannels(PKG,
    341                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
    342         assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null);
    343         assertTrue(mBinderService.getNotificationChannel(PKG, "id2") != null);
    344     }
    345 
    346     @Test
    347     public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance()
    348             throws Exception {
    349         final NotificationChannel channel =
    350                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
    351         mBinderService.createNotificationChannels(PKG,
    352                 new ParceledListSlice(Arrays.asList(channel)));
    353 
    354         // Recreating the channel doesn't throw, but ignores importance.
    355         final NotificationChannel dupeChannel =
    356                 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
    357         mBinderService.createNotificationChannels(PKG,
    358                 new ParceledListSlice(Arrays.asList(dupeChannel)));
    359         final NotificationChannel createdChannel =
    360                 mBinderService.getNotificationChannel(PKG, "id");
    361         assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
    362     }
    363 
    364     @Test
    365     public void testCreateNotificationChannels_SecondCreateAllowedToDowngradeImportance()
    366             throws Exception {
    367         final NotificationChannel channel =
    368                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
    369         mBinderService.createNotificationChannels(PKG,
    370                 new ParceledListSlice(Arrays.asList(channel)));
    371 
    372         // Recreating with a lower importance is allowed to modify the channel.
    373         final NotificationChannel dupeChannel =
    374                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
    375         mBinderService.createNotificationChannels(PKG,
    376                 new ParceledListSlice(Arrays.asList(dupeChannel)));
    377         final NotificationChannel createdChannel =
    378                 mBinderService.getNotificationChannel(PKG, "id");
    379         assertEquals(NotificationManager.IMPORTANCE_LOW, createdChannel.getImportance());
    380     }
    381 
    382     @Test
    383     public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated()
    384             throws Exception {
    385         final NotificationChannel channel =
    386                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
    387         mBinderService.createNotificationChannels(PKG,
    388                 new ParceledListSlice(Arrays.asList(channel)));
    389 
    390         // The user modifies importance directly, can no longer be changed by the app.
    391         final NotificationChannel updatedChannel =
    392                 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
    393         mBinderService.updateNotificationChannelForPackage(PKG, mUid, updatedChannel);
    394 
    395         // Recreating with a lower importance leaves channel unchanged.
    396         final NotificationChannel dupeChannel =
    397                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
    398         mBinderService.createNotificationChannels(PKG,
    399                 new ParceledListSlice(Arrays.asList(dupeChannel)));
    400         final NotificationChannel createdChannel =
    401                 mBinderService.getNotificationChannel(PKG, "id");
    402         assertEquals(IMPORTANCE_HIGH, createdChannel.getImportance());
    403     }
    404 
    405     @Test
    406     public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond()
    407             throws Exception {
    408         final NotificationChannel channel1 =
    409                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
    410         final NotificationChannel channel2 =
    411                 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
    412         mBinderService.createNotificationChannels(PKG,
    413                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
    414         final NotificationChannel createdChannel =
    415                 mBinderService.getNotificationChannel(PKG, "id");
    416         assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
    417     }
    418 
    419     @Test
    420     public void testBlockedNotifications_suspended() throws Exception {
    421         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(true);
    422 
    423         NotificationChannel channel = new NotificationChannel("id", "name",
    424                 IMPORTANCE_HIGH);
    425         NotificationRecord r = generateNotificationRecord(channel);
    426         assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats));
    427         verify(mUsageStats, times(1)).registerSuspendedByAdmin(eq(r));
    428     }
    429 
    430     @Test
    431     public void testBlockedNotifications_blockedChannel() throws Exception {
    432         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    433 
    434         NotificationChannel channel = new NotificationChannel("id", "name",
    435                 NotificationManager.IMPORTANCE_NONE);
    436         NotificationRecord r = generateNotificationRecord(channel);
    437         assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats));
    438         verify(mUsageStats, times(1)).registerBlocked(eq(r));
    439 
    440         mBinderService.createNotificationChannels(
    441                 PKG, new ParceledListSlice(Arrays.asList(channel)));
    442         final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
    443         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    444                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    445         waitForIdle();
    446         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    447     }
    448 
    449     @Test
    450     public void testEnqueuedBlockedNotifications_appBlockedChannelForegroundService()
    451             throws Exception {
    452         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    453 
    454         NotificationChannel channel = new NotificationChannel("blocked", "name",
    455                 NotificationManager.IMPORTANCE_NONE);
    456         mBinderService.createNotificationChannels(
    457                 PKG, new ParceledListSlice(Arrays.asList(channel)));
    458 
    459         final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
    460         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
    461         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    462                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    463         waitForIdle();
    464         assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    465         assertEquals(IMPORTANCE_LOW,
    466                 mNotificationManagerService.getNotificationRecord(sbn.getKey()).getImportance());
    467         assertEquals(IMPORTANCE_LOW,
    468                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
    469     }
    470 
    471     @Test
    472     public void testEnqueuedBlockedNotifications_userBlockedChannelForegroundService()
    473             throws Exception {
    474         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    475 
    476         NotificationChannel channel =
    477                 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_HIGH);
    478         mBinderService.createNotificationChannels(
    479                 PKG, new ParceledListSlice(Arrays.asList(channel)));
    480 
    481         NotificationChannel update =
    482                 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
    483         mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
    484         waitForIdle();
    485         assertEquals(IMPORTANCE_NONE,
    486                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
    487 
    488         final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
    489         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
    490         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    491                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    492         waitForIdle();
    493         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    494         assertNull(mNotificationManagerService.getNotificationRecord(sbn.getKey()));
    495         assertEquals(IMPORTANCE_NONE,
    496                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
    497     }
    498 
    499     @Test
    500     public void testEnqueuedBlockedNotifications_blockedApp() throws Exception {
    501         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    502 
    503         mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
    504 
    505         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    506         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    507                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    508         waitForIdle();
    509         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    510     }
    511 
    512     @Test
    513     public void testEnqueuedBlockedNotifications_blockedAppForegroundService() throws Exception {
    514         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    515 
    516         mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
    517 
    518         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    519         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
    520         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    521                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    522         waitForIdle();
    523         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    524         assertNull(mNotificationManagerService.getNotificationRecord(sbn.getKey()));
    525     }
    526 
    527     @Test
    528     public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
    529         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
    530                 generateNotificationRecord(null).getNotification(), 0);
    531         waitForIdle();
    532         StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
    533         assertEquals(1, notifs.length);
    534         assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
    535     }
    536 
    537     @Test
    538     public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
    539         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
    540                 generateNotificationRecord(null).getNotification(), 0);
    541         mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
    542         waitForIdle();
    543         StatusBarNotification[] notifs =
    544                 mBinderService.getActiveNotifications(PKG);
    545         assertEquals(0, notifs.length);
    546         assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
    547     }
    548 
    549     @Test
    550     public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
    551         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
    552                 generateNotificationRecord(null).getNotification(), 0);
    553         waitForIdle();
    554         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
    555                 generateNotificationRecord(null).getNotification(), 0);
    556         mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
    557         waitForIdle();
    558         StatusBarNotification[] notifs =
    559                 mBinderService.getActiveNotifications(PKG);
    560         assertEquals(0, notifs.length);
    561         assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
    562     }
    563 
    564     @Test
    565     public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
    566         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    567         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    568                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    569         mBinderService.cancelNotificationsFromListener(null, null);
    570         waitForIdle();
    571         StatusBarNotification[] notifs =
    572                 mBinderService.getActiveNotifications(sbn.getPackageName());
    573         assertEquals(0, notifs.length);
    574         assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
    575     }
    576 
    577     @Test
    578     public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
    579         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    580         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    581                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    582         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
    583         waitForIdle();
    584         StatusBarNotification[] notifs =
    585                 mBinderService.getActiveNotifications(sbn.getPackageName());
    586         assertEquals(0, notifs.length);
    587         assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
    588     }
    589 
    590     @Test
    591     public void testUserInitiatedClearAll_noLeak() throws Exception {
    592         final NotificationRecord n = generateNotificationRecord(
    593                 mTestNotificationChannel, 1, "group", true);
    594 
    595         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    596                 n.sbn.getId(), n.sbn.getNotification(), n.sbn.getUserId());
    597         waitForIdle();
    598 
    599         mNotificationManagerService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
    600                 n.getUserId());
    601         waitForIdle();
    602         StatusBarNotification[] notifs =
    603                 mBinderService.getActiveNotifications(n.sbn.getPackageName());
    604         assertEquals(0, notifs.length);
    605         assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
    606     }
    607 
    608     @Test
    609     public void testCancelAllNotificationsCancelsChildren() throws Exception {
    610         final NotificationRecord parent = generateNotificationRecord(
    611                 mTestNotificationChannel, 1, "group1", true);
    612         final NotificationRecord child = generateNotificationRecord(
    613                 mTestNotificationChannel, 2, "group1", false);
    614 
    615         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    616                 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
    617         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    618                 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
    619         waitForIdle();
    620 
    621         mBinderService.cancelAllNotifications(PKG, parent.sbn.getUserId());
    622         waitForIdle();
    623         assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
    624     }
    625 
    626     @Test
    627     public void testCancelAllNotificationsMultipleEnqueuedDoesNotCrash() throws Exception {
    628         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    629         for (int i = 0; i < 10; i++) {
    630             mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    631                     sbn.getId(), sbn.getNotification(), sbn.getUserId());
    632         }
    633         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
    634         waitForIdle();
    635 
    636         assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
    637     }
    638 
    639     @Test
    640     public void testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash() throws Exception {
    641         final NotificationRecord parent = generateNotificationRecord(
    642                 mTestNotificationChannel, 1, "group1", true);
    643         final NotificationRecord parentAsChild = generateNotificationRecord(
    644                 mTestNotificationChannel, 1, "group1", false);
    645         final NotificationRecord child = generateNotificationRecord(
    646                 mTestNotificationChannel, 2, "group1", false);
    647 
    648         // fully post parent notification
    649         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    650                 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
    651         waitForIdle();
    652 
    653         // enqueue the child several times
    654         for (int i = 0; i < 10; i++) {
    655             mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    656                     child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
    657         }
    658         // make the parent a child, which will cancel the child notification
    659         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    660                 parentAsChild.sbn.getId(), parentAsChild.sbn.getNotification(),
    661                 parentAsChild.sbn.getUserId());
    662         waitForIdle();
    663 
    664         assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
    665     }
    666 
    667     @Test
    668     public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
    669         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    670         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
    671         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    672                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    673         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
    674         waitForIdle();
    675         StatusBarNotification[] notifs =
    676                 mBinderService.getActiveNotifications(sbn.getPackageName());
    677         assertEquals(1, notifs.length);
    678         assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
    679     }
    680 
    681     @Test
    682     public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
    683         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    684         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
    685         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    686                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    687         mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
    688         waitForIdle();
    689         StatusBarNotification[] notifs =
    690                 mBinderService.getActiveNotifications(sbn.getPackageName());
    691         assertEquals(1, notifs.length);
    692         assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
    693     }
    694 
    695     @Test
    696     public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
    697         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    698         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    699                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    700         mBinderService.cancelAllNotifications(null, sbn.getUserId());
    701         waitForIdle();
    702         StatusBarNotification[] notifs =
    703                 mBinderService.getActiveNotifications(sbn.getPackageName());
    704         assertEquals(0, notifs.length);
    705         assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
    706     }
    707 
    708     @Test
    709     public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
    710         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    711         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    712                 sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL);
    713         // Null pkg is how we signal a user switch.
    714         mBinderService.cancelAllNotifications(null, sbn.getUserId());
    715         waitForIdle();
    716         StatusBarNotification[] notifs =
    717                 mBinderService.getActiveNotifications(sbn.getPackageName());
    718         assertEquals(1, notifs.length);
    719         assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
    720     }
    721 
    722     @Test
    723     public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception {
    724         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    725         sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR;
    726         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    727                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    728         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
    729         waitForIdle();
    730         StatusBarNotification[] notifs =
    731                 mBinderService.getActiveNotifications(sbn.getPackageName());
    732         assertEquals(0, notifs.length);
    733     }
    734 
    735     @Test
    736     public void testCancelAllNotifications_CancelsNoClearFlag() throws Exception {
    737         final NotificationRecord notif = generateNotificationRecord(
    738                 mTestNotificationChannel, 1, "group", true);
    739         notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
    740         mNotificationManagerService.addNotification(notif);
    741         mNotificationManagerService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true,
    742                 notif.getUserId(), 0, null);
    743         waitForIdle();
    744         StatusBarNotification[] notifs =
    745                 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
    746         assertEquals(0, notifs.length);
    747     }
    748 
    749     @Test
    750     public void testUserInitiatedCancelAllOnClearAll_NoClearFlag() throws Exception {
    751         final NotificationRecord notif = generateNotificationRecord(
    752                 mTestNotificationChannel, 1, "group", true);
    753         notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
    754         mNotificationManagerService.addNotification(notif);
    755 
    756         mNotificationManagerService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
    757                 notif.getUserId());
    758         waitForIdle();
    759         StatusBarNotification[] notifs =
    760                 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
    761         assertEquals(1, notifs.length);
    762     }
    763 
    764     @Test
    765     public void testCancelAllCancelNotificationsFromListener_NoClearFlag() throws Exception {
    766         final NotificationRecord parent = generateNotificationRecord(
    767                 mTestNotificationChannel, 1, "group", true);
    768         final NotificationRecord child = generateNotificationRecord(
    769                 mTestNotificationChannel, 2, "group", false);
    770         final NotificationRecord child2 = generateNotificationRecord(
    771                 mTestNotificationChannel, 3, "group", false);
    772         child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
    773         final NotificationRecord newGroup = generateNotificationRecord(
    774                 mTestNotificationChannel, 4, "group2", false);
    775         mNotificationManagerService.addNotification(parent);
    776         mNotificationManagerService.addNotification(child);
    777         mNotificationManagerService.addNotification(child2);
    778         mNotificationManagerService.addNotification(newGroup);
    779         mNotificationManagerService.getBinderService().cancelNotificationsFromListener(null, null);
    780         waitForIdle();
    781         StatusBarNotification[] notifs =
    782                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
    783         assertEquals(1, notifs.length);
    784     }
    785 
    786     @Test
    787     public void testUserInitiatedCancelAllWithGroup_NoClearFlag() throws Exception {
    788         final NotificationRecord parent = generateNotificationRecord(
    789                 mTestNotificationChannel, 1, "group", true);
    790         final NotificationRecord child = generateNotificationRecord(
    791                 mTestNotificationChannel, 2, "group", false);
    792         final NotificationRecord child2 = generateNotificationRecord(
    793                 mTestNotificationChannel, 3, "group", false);
    794         child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
    795         final NotificationRecord newGroup = generateNotificationRecord(
    796                 mTestNotificationChannel, 4, "group2", false);
    797         mNotificationManagerService.addNotification(parent);
    798         mNotificationManagerService.addNotification(child);
    799         mNotificationManagerService.addNotification(child2);
    800         mNotificationManagerService.addNotification(newGroup);
    801         mNotificationManagerService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
    802                 parent.getUserId());
    803         waitForIdle();
    804         StatusBarNotification[] notifs =
    805                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
    806         assertEquals(1, notifs.length);
    807     }
    808 
    809     @Test
    810     public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
    811         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    812         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
    813         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
    814                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    815         mInternalService.removeForegroundServiceFlagFromNotification(PKG, sbn.getId(),
    816                 sbn.getUserId());
    817         waitForIdle();
    818         StatusBarNotification[] notifs =
    819                 mBinderService.getActiveNotifications(sbn.getPackageName());
    820         assertEquals(0, notifs[0].getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE);
    821     }
    822 
    823     @Test
    824     public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception {
    825         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    826         sbn.getNotification().flags =
    827                 Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE;
    828         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    829                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    830         sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
    831         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    832                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    833         mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
    834         waitForIdle();
    835         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    836         assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
    837     }
    838 
    839     @Test
    840     public void testFindGroupNotificationsLocked() throws Exception {
    841         // make sure the same notification can be found in both lists and returned
    842         final NotificationRecord group1 = generateNotificationRecord(
    843                 mTestNotificationChannel, 1, "group1", true);
    844         mNotificationManagerService.addEnqueuedNotification(group1);
    845         mNotificationManagerService.addNotification(group1);
    846 
    847         // should not be returned
    848         final NotificationRecord group2 = generateNotificationRecord(
    849                 mTestNotificationChannel, 2, "group2", true);
    850         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
    851                 group2.sbn.getId(), group2.sbn.getNotification(), group2.sbn.getUserId());
    852         waitForIdle();
    853 
    854         // should not be returned
    855         final NotificationRecord nonGroup = generateNotificationRecord(
    856                 mTestNotificationChannel, 3, null, false);
    857         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
    858                 nonGroup.sbn.getId(), nonGroup.sbn.getNotification(), nonGroup.sbn.getUserId());
    859         waitForIdle();
    860 
    861         // same group, child, should be returned
    862         final NotificationRecord group1Child = generateNotificationRecord(
    863                 mTestNotificationChannel, 4, "group1", false);
    864         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, group1Child.sbn.getId(),
    865                 group1Child.sbn.getNotification(), group1Child.sbn.getUserId());
    866         waitForIdle();
    867 
    868         List<NotificationRecord> inGroup1 =
    869                 mNotificationManagerService.findGroupNotificationsLocked(PKG, group1.getGroupKey(),
    870                         group1.sbn.getUserId());
    871         assertEquals(3, inGroup1.size());
    872         for (NotificationRecord record : inGroup1) {
    873             assertTrue(record.getGroupKey().equals(group1.getGroupKey()));
    874             assertTrue(record.sbn.getId() == 1 || record.sbn.getId() == 4);
    875         }
    876     }
    877 
    878     @Test
    879     public void testTvExtenderChannelOverride_onTv() throws Exception {
    880         mNotificationManagerService.setIsTelevision(true);
    881         mNotificationManagerService.setRankingHelper(mRankingHelper);
    882         when(mRankingHelper.getNotificationChannel(
    883                 anyString(), anyInt(), eq("foo"), anyBoolean())).thenReturn(
    884                         new NotificationChannel("foo", "foo", IMPORTANCE_HIGH));
    885 
    886         Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
    887         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
    888                 generateNotificationRecord(null, tv).getNotification(), 0);
    889         verify(mRankingHelper, times(1)).getNotificationChannel(
    890                 anyString(), anyInt(), eq("foo"), anyBoolean());
    891     }
    892 
    893     @Test
    894     public void testTvExtenderChannelOverride_notOnTv() throws Exception {
    895         mNotificationManagerService.setIsTelevision(false);
    896         mNotificationManagerService.setRankingHelper(mRankingHelper);
    897         when(mRankingHelper.getNotificationChannel(
    898                 anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
    899                 mTestNotificationChannel);
    900 
    901         Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
    902         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
    903                 generateNotificationRecord(null, tv).getNotification(), 0);
    904         verify(mRankingHelper, times(1)).getNotificationChannel(
    905                 anyString(), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean());
    906     }
    907 
    908     @Test
    909     public void testCreateChannelNotifyListener() throws Exception {
    910         List<String> associations = new ArrayList<>();
    911         associations.add("a");
    912         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
    913         mNotificationManagerService.setRankingHelper(mRankingHelper);
    914         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
    915                 eq(mTestNotificationChannel.getId()), anyBoolean()))
    916                 .thenReturn(mTestNotificationChannel);
    917         NotificationChannel channel2 = new NotificationChannel("a", "b", IMPORTANCE_LOW);
    918         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
    919                 eq(channel2.getId()), anyBoolean()))
    920                 .thenReturn(channel2);
    921 
    922         reset(mListeners);
    923         mBinderService.createNotificationChannels(PKG,
    924                 new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
    925         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
    926                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
    927                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
    928         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
    929                 eq(Process.myUserHandle()), eq(channel2),
    930                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
    931     }
    932 
    933     @Test
    934     public void testCreateChannelGroupNotifyListener() throws Exception {
    935         List<String> associations = new ArrayList<>();
    936         associations.add("a");
    937         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
    938         mNotificationManagerService.setRankingHelper(mRankingHelper);
    939         NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
    940         NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
    941 
    942         reset(mListeners);
    943         mBinderService.createNotificationChannelGroups(PKG,
    944                 new ParceledListSlice(Arrays.asList(group1, group2)));
    945         verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
    946                 eq(Process.myUserHandle()), eq(group1),
    947                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
    948         verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
    949                 eq(Process.myUserHandle()), eq(group2),
    950                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
    951     }
    952 
    953     @Test
    954     public void testUpdateChannelNotifyListener() throws Exception {
    955         List<String> associations = new ArrayList<>();
    956         associations.add("a");
    957         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
    958         mNotificationManagerService.setRankingHelper(mRankingHelper);
    959         mTestNotificationChannel.setLightColor(Color.CYAN);
    960         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
    961                 eq(mTestNotificationChannel.getId()), anyBoolean()))
    962                 .thenReturn(mTestNotificationChannel);
    963 
    964         reset(mListeners);
    965         mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
    966         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
    967                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
    968                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
    969     }
    970 
    971     @Test
    972     public void testDeleteChannelNotifyListener() throws Exception {
    973         List<String> associations = new ArrayList<>();
    974         associations.add("a");
    975         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
    976         mNotificationManagerService.setRankingHelper(mRankingHelper);
    977         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
    978                 eq(mTestNotificationChannel.getId()), anyBoolean()))
    979                 .thenReturn(mTestNotificationChannel);
    980         reset(mListeners);
    981         mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
    982         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
    983                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
    984                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
    985     }
    986 
    987     @Test
    988     public void testDeleteChannelGroupNotifyListener() throws Exception {
    989         List<String> associations = new ArrayList<>();
    990         associations.add("a");
    991         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
    992         NotificationChannelGroup ncg = new NotificationChannelGroup("a", "b/c");
    993         mNotificationManagerService.setRankingHelper(mRankingHelper);
    994         when(mRankingHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt()))
    995                 .thenReturn(ncg);
    996         reset(mListeners);
    997         mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId());
    998         verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
    999                 eq(Process.myUserHandle()), eq(ncg),
   1000                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
   1001     }
   1002 
   1003     @Test
   1004     public void testUpdateNotificationChannelFromPrivilegedListener_success() throws Exception {
   1005         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1006         List<String> associations = new ArrayList<>();
   1007         associations.add("a");
   1008         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1009 
   1010         mBinderService.updateNotificationChannelFromPrivilegedListener(
   1011                 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
   1012 
   1013         verify(mRankingHelper, times(1)).updateNotificationChannel(
   1014                 anyString(), anyInt(), any(), anyBoolean());
   1015 
   1016         verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
   1017                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
   1018                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
   1019     }
   1020 
   1021     @Test
   1022     public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
   1023         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1024         List<String> associations = new ArrayList<>();
   1025         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1026 
   1027         try {
   1028             mBinderService.updateNotificationChannelFromPrivilegedListener(
   1029                     null, PKG, Process.myUserHandle(), mTestNotificationChannel);
   1030             fail("listeners that don't have a companion device shouldn't be able to call this");
   1031         } catch (SecurityException e) {
   1032             // pass
   1033         }
   1034 
   1035         verify(mRankingHelper, never()).updateNotificationChannel(
   1036                 anyString(), anyInt(), any(), anyBoolean());
   1037 
   1038         verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
   1039                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
   1040                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
   1041     }
   1042 
   1043     @Test
   1044     public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
   1045         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1046         List<String> associations = new ArrayList<>();
   1047         associations.add("a");
   1048         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1049         mListener = mock(ManagedServices.ManagedServiceInfo.class);
   1050         mListener.component = new ComponentName(PKG, PKG);
   1051         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
   1052         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
   1053 
   1054         try {
   1055             mBinderService.updateNotificationChannelFromPrivilegedListener(
   1056                     null, PKG, UserHandle.ALL, mTestNotificationChannel);
   1057             fail("incorrectly allowed a change to a user listener cannot see");
   1058         } catch (SecurityException e) {
   1059             // pass
   1060         }
   1061 
   1062         verify(mRankingHelper, never()).updateNotificationChannel(
   1063                 anyString(), anyInt(), any(), anyBoolean());
   1064 
   1065         verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
   1066                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
   1067                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
   1068     }
   1069 
   1070     @Test
   1071     public void testGetNotificationChannelFromPrivilegedListener_success() throws Exception {
   1072         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1073         List<String> associations = new ArrayList<>();
   1074         associations.add("a");
   1075         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1076 
   1077         mBinderService.getNotificationChannelsFromPrivilegedListener(
   1078                 null, PKG, Process.myUserHandle());
   1079 
   1080         verify(mRankingHelper, times(1)).getNotificationChannels(
   1081                 anyString(), anyInt(), anyBoolean());
   1082     }
   1083 
   1084     @Test
   1085     public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
   1086         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1087         List<String> associations = new ArrayList<>();
   1088         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1089 
   1090         try {
   1091             mBinderService.getNotificationChannelsFromPrivilegedListener(
   1092                     null, PKG, Process.myUserHandle());
   1093             fail("listeners that don't have a companion device shouldn't be able to call this");
   1094         } catch (SecurityException e) {
   1095             // pass
   1096         }
   1097 
   1098         verify(mRankingHelper, never()).getNotificationChannels(
   1099                 anyString(), anyInt(), anyBoolean());
   1100     }
   1101 
   1102     @Test
   1103     public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
   1104         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1105         List<String> associations = new ArrayList<>();
   1106         associations.add("a");
   1107         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1108         mListener = mock(ManagedServices.ManagedServiceInfo.class);
   1109         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
   1110         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
   1111 
   1112         try {
   1113             mBinderService.getNotificationChannelsFromPrivilegedListener(
   1114                     null, PKG, Process.myUserHandle());
   1115             fail("listener getting channels from a user they cannot see");
   1116         } catch (SecurityException e) {
   1117             // pass
   1118         }
   1119 
   1120         verify(mRankingHelper, never()).getNotificationChannels(
   1121                 anyString(), anyInt(), anyBoolean());
   1122     }
   1123 
   1124     @Test
   1125     public void testGetNotificationChannelGroupsFromPrivilegedListener_success() throws Exception {
   1126         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1127         List<String> associations = new ArrayList<>();
   1128         associations.add("a");
   1129         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1130 
   1131         mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
   1132                 null, PKG, Process.myUserHandle());
   1133 
   1134         verify(mRankingHelper, times(1)).getNotificationChannelGroups(anyString(), anyInt());
   1135     }
   1136 
   1137     @Test
   1138     public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception {
   1139         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1140         List<String> associations = new ArrayList<>();
   1141         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1142 
   1143         try {
   1144             mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
   1145                     null, PKG, Process.myUserHandle());
   1146             fail("listeners that don't have a companion device shouldn't be able to call this");
   1147         } catch (SecurityException e) {
   1148             // pass
   1149         }
   1150 
   1151         verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
   1152     }
   1153 
   1154     @Test
   1155     public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
   1156         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1157         List<String> associations = new ArrayList<>();
   1158         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1159         mListener = mock(ManagedServices.ManagedServiceInfo.class);
   1160         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
   1161         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
   1162 
   1163         try {
   1164             mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
   1165                     null, PKG, Process.myUserHandle());
   1166             fail("listeners that don't have a companion device shouldn't be able to call this");
   1167         } catch (SecurityException e) {
   1168             // pass
   1169         }
   1170 
   1171         verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
   1172     }
   1173 
   1174     @Test
   1175     public void testHasCompanionDevice_failure() throws Exception {
   1176         when(mCompanionMgr.getAssociations(anyString(), anyInt())).thenThrow(
   1177                 new IllegalArgumentException());
   1178         mNotificationManagerService.hasCompanionDevice(mListener);
   1179     }
   1180 
   1181     @Test
   1182     public void testHasCompanionDevice_noService() throws Exception {
   1183         mNotificationManagerService = new TestableNotificationManagerService(mContext);
   1184 
   1185         assertFalse(mNotificationManagerService.hasCompanionDevice(mListener));
   1186     }
   1187 
   1188     @Test
   1189     public void testSnoozeRunnable_snoozeNonGrouped() throws Exception {
   1190         final NotificationRecord nonGrouped = generateNotificationRecord(
   1191                 mTestNotificationChannel, 1, null, false);
   1192         final NotificationRecord grouped = generateNotificationRecord(
   1193                 mTestNotificationChannel, 2, "group", false);
   1194         mNotificationManagerService.addNotification(grouped);
   1195         mNotificationManagerService.addNotification(nonGrouped);
   1196 
   1197         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
   1198                 mNotificationManagerService.new SnoozeNotificationRunnable(
   1199                         nonGrouped.getKey(), 100, null);
   1200         snoozeNotificationRunnable.run();
   1201 
   1202         // only snooze the one notification
   1203         verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
   1204     }
   1205 
   1206     @Test
   1207     public void testSnoozeRunnable_snoozeSummary_withChildren() throws Exception {
   1208         final NotificationRecord parent = generateNotificationRecord(
   1209                 mTestNotificationChannel, 1, "group", true);
   1210         final NotificationRecord child = generateNotificationRecord(
   1211                 mTestNotificationChannel, 2, "group", false);
   1212         final NotificationRecord child2 = generateNotificationRecord(
   1213                 mTestNotificationChannel, 3, "group", false);
   1214         mNotificationManagerService.addNotification(parent);
   1215         mNotificationManagerService.addNotification(child);
   1216         mNotificationManagerService.addNotification(child2);
   1217 
   1218         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
   1219                 mNotificationManagerService.new SnoozeNotificationRunnable(
   1220                         parent.getKey(), 100, null);
   1221         snoozeNotificationRunnable.run();
   1222 
   1223         // snooze parent and children
   1224         verify(mSnoozeHelper, times(3)).snooze(any(NotificationRecord.class), anyLong());
   1225     }
   1226 
   1227     @Test
   1228     public void testSnoozeRunnable_snoozeGroupChild_fellowChildren() throws Exception {
   1229         final NotificationRecord parent = generateNotificationRecord(
   1230                 mTestNotificationChannel, 1, "group", true);
   1231         final NotificationRecord child = generateNotificationRecord(
   1232                 mTestNotificationChannel, 2, "group", false);
   1233         final NotificationRecord child2 = generateNotificationRecord(
   1234                 mTestNotificationChannel, 3, "group", false);
   1235         mNotificationManagerService.addNotification(parent);
   1236         mNotificationManagerService.addNotification(child);
   1237         mNotificationManagerService.addNotification(child2);
   1238 
   1239         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
   1240                 mNotificationManagerService.new SnoozeNotificationRunnable(
   1241                         child2.getKey(), 100, null);
   1242         snoozeNotificationRunnable.run();
   1243 
   1244         // only snooze the one child
   1245         verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
   1246     }
   1247 
   1248     @Test
   1249     public void testSnoozeRunnable_snoozeGroupChild_onlyChildOfSummary() throws Exception {
   1250         final NotificationRecord parent = generateNotificationRecord(
   1251                 mTestNotificationChannel, 1, "group", true);
   1252         assertTrue(parent.sbn.getNotification().isGroupSummary());
   1253         final NotificationRecord child = generateNotificationRecord(
   1254                 mTestNotificationChannel, 2, "group", false);
   1255         mNotificationManagerService.addNotification(parent);
   1256         mNotificationManagerService.addNotification(child);
   1257 
   1258         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
   1259                 mNotificationManagerService.new SnoozeNotificationRunnable(
   1260                         child.getKey(), 100, null);
   1261         snoozeNotificationRunnable.run();
   1262 
   1263         // snooze child and summary
   1264         verify(mSnoozeHelper, times(2)).snooze(any(NotificationRecord.class), anyLong());
   1265     }
   1266 
   1267     @Test
   1268     public void testSnoozeRunnable_snoozeGroupChild_noOthersInGroup() throws Exception {
   1269         final NotificationRecord child = generateNotificationRecord(
   1270                 mTestNotificationChannel, 2, "group", false);
   1271         mNotificationManagerService.addNotification(child);
   1272 
   1273         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
   1274                 mNotificationManagerService.new SnoozeNotificationRunnable(
   1275                         child.getKey(), 100, null);
   1276         snoozeNotificationRunnable.run();
   1277 
   1278         // snooze child only
   1279         verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
   1280     }
   1281 
   1282     @Test
   1283     public void testPostGroupChild_unsnoozeParent() throws Exception {
   1284         final NotificationRecord child = generateNotificationRecord(
   1285                 mTestNotificationChannel, 2, "group", false);
   1286 
   1287         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
   1288                 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
   1289         waitForIdle();
   1290 
   1291         verify(mSnoozeHelper, times(1)).repostGroupSummary(
   1292                 anyString(), anyInt(), eq(child.getGroupKey()));
   1293     }
   1294 
   1295     @Test
   1296     public void testPostNonGroup_noUnsnoozing() throws Exception {
   1297         final NotificationRecord record = generateNotificationRecord(
   1298                 mTestNotificationChannel, 2, null, false);
   1299 
   1300         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
   1301                 record.sbn.getId(), record.sbn.getNotification(), record.sbn.getUserId());
   1302         waitForIdle();
   1303 
   1304         verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
   1305     }
   1306 
   1307     @Test
   1308     public void testPostGroupSummary_noUnsnoozing() throws Exception {
   1309         final NotificationRecord parent = generateNotificationRecord(
   1310                 mTestNotificationChannel, 2, "group", true);
   1311 
   1312         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
   1313                 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
   1314         waitForIdle();
   1315 
   1316         verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
   1317     }
   1318 
   1319     @Test
   1320     public void testSetListenerAccessForUser() throws Exception {
   1321         UserHandle user = UserHandle.of(10);
   1322         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1323         try {
   1324             mBinderService.setNotificationListenerAccessGrantedForUser(
   1325                     c, user.getIdentifier(), true);
   1326         } catch (SecurityException e) {
   1327             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1328                 throw e;
   1329             }
   1330         }
   1331 
   1332         verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
   1333         verify(mListeners, times(1)).setPackageOrComponentEnabled(
   1334                 c.flattenToString(), user.getIdentifier(), true, true);
   1335         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1336                 c.flattenToString(), user.getIdentifier(), false, true);
   1337         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1338                 any(), anyInt(), anyBoolean(), anyBoolean());
   1339     }
   1340 
   1341     @Test
   1342     public void testSetAssistantAccessForUser() throws Exception {
   1343         UserHandle user = UserHandle.of(10);
   1344         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1345         try {
   1346             mBinderService.setNotificationAssistantAccessGrantedForUser(
   1347                     c, user.getIdentifier(), true);
   1348         } catch (SecurityException e) {
   1349             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1350                 throw e;
   1351             }
   1352         }
   1353 
   1354         verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
   1355         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
   1356                 c.flattenToString(), user.getIdentifier(), true, true);
   1357         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1358                 c.flattenToString(), user.getIdentifier(), false, true);
   1359         verify(mListeners, never()).setPackageOrComponentEnabled(
   1360                 any(), anyInt(), anyBoolean(), anyBoolean());
   1361     }
   1362 
   1363     @Test
   1364     public void testSetDndAccessForUser() throws Exception {
   1365         UserHandle user = UserHandle.of(10);
   1366         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1367         try {
   1368             mBinderService.setNotificationPolicyAccessGrantedForUser(
   1369                     c.getPackageName(), user.getIdentifier(), true);
   1370         } catch (SecurityException e) {
   1371             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1372                 throw e;
   1373             }
   1374         }
   1375 
   1376         verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
   1377         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1378                 c.getPackageName(), user.getIdentifier(), true, true);
   1379         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1380                 any(), anyInt(), anyBoolean(), anyBoolean());
   1381         verify(mListeners, never()).setPackageOrComponentEnabled(
   1382                 any(), anyInt(), anyBoolean(), anyBoolean());
   1383     }
   1384 
   1385     @Test
   1386     public void testSetListenerAccess() throws Exception {
   1387         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1388         try {
   1389             mBinderService.setNotificationListenerAccessGranted(c, true);
   1390         } catch (SecurityException e) {
   1391             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1392                 throw e;
   1393             }
   1394         }
   1395 
   1396         verify(mListeners, times(1)).setPackageOrComponentEnabled(
   1397                 c.flattenToString(), 0, true, true);
   1398         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1399                 c.flattenToString(), 0, false, true);
   1400         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1401                 any(), anyInt(), anyBoolean(), anyBoolean());
   1402     }
   1403 
   1404     @Test
   1405     public void testSetAssistantAccess() throws Exception {
   1406         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1407         try {
   1408             mBinderService.setNotificationAssistantAccessGranted(c, true);
   1409         } catch (SecurityException e) {
   1410             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1411                 throw e;
   1412             }
   1413         }
   1414 
   1415         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
   1416                 c.flattenToString(), 0, true, true);
   1417         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1418                 c.flattenToString(), 0, false, true);
   1419         verify(mListeners, never()).setPackageOrComponentEnabled(
   1420                 any(), anyInt(), anyBoolean(), anyBoolean());
   1421     }
   1422 
   1423     @Test
   1424     public void testSetDndAccess() throws Exception {
   1425         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1426         try {
   1427             mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
   1428         } catch (SecurityException e) {
   1429             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1430                 throw e;
   1431             }
   1432         }
   1433 
   1434         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1435                 c.getPackageName(), 0, true, true);
   1436         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1437                 any(), anyInt(), anyBoolean(), anyBoolean());
   1438         verify(mListeners, never()).setPackageOrComponentEnabled(
   1439                 any(), anyInt(), anyBoolean(), anyBoolean());
   1440     }
   1441 
   1442     @Test
   1443     public void testSetListenerAccess_doesNothingOnLowRam() throws Exception {
   1444         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   1445         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1446         mBinderService.setNotificationListenerAccessGranted(c, true);
   1447 
   1448         verify(mListeners, never()).setPackageOrComponentEnabled(
   1449                 c.flattenToString(), 0, true, true);
   1450         verify(mConditionProviders, never()).setPackageOrComponentEnabled(
   1451                 c.flattenToString(), 0, false, true);
   1452         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1453                 any(), anyInt(), anyBoolean(), anyBoolean());
   1454     }
   1455 
   1456     @Test
   1457     public void testSetAssistantAccess_doesNothingOnLowRam() throws Exception {
   1458         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   1459         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1460         mBinderService.setNotificationAssistantAccessGranted(c, true);
   1461 
   1462 
   1463         verify(mListeners, never()).setPackageOrComponentEnabled(
   1464                 c.flattenToString(), 0, true, true);
   1465         verify(mConditionProviders, never()).setPackageOrComponentEnabled(
   1466                 c.flattenToString(), 0, false, true);
   1467         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1468                 any(), anyInt(), anyBoolean(), anyBoolean());
   1469     }
   1470 
   1471     @Test
   1472     public void testSetDndAccess_doesNothingOnLowRam() throws Exception {
   1473         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   1474         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1475         mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
   1476 
   1477         verify(mListeners, never()).setPackageOrComponentEnabled(
   1478                 c.flattenToString(), 0, true, true);
   1479         verify(mConditionProviders, never()).setPackageOrComponentEnabled(
   1480                 c.flattenToString(), 0, false, true);
   1481         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1482                 any(), anyInt(), anyBoolean(), anyBoolean());
   1483     }
   1484 
   1485     @Test
   1486     public void testOnlyAutogroupIfGroupChanged_noPriorNoti_autogroups() throws Exception {
   1487         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
   1488         mNotificationManagerService.addEnqueuedNotification(r);
   1489         NotificationManagerService.PostNotificationRunnable runnable =
   1490                 mNotificationManagerService.new PostNotificationRunnable(r.getKey());
   1491         runnable.run();
   1492         waitForIdle();
   1493 
   1494         verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
   1495     }
   1496 
   1497     @Test
   1498     public void testOnlyAutogroupIfGroupChanged_groupChanged_autogroups()
   1499             throws Exception {
   1500         NotificationRecord r =
   1501                 generateNotificationRecord(mTestNotificationChannel, 0, "group", false);
   1502         mNotificationManagerService.addNotification(r);
   1503 
   1504         r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
   1505         mNotificationManagerService.addEnqueuedNotification(r);
   1506         NotificationManagerService.PostNotificationRunnable runnable =
   1507                 mNotificationManagerService.new PostNotificationRunnable(r.getKey());
   1508         runnable.run();
   1509         waitForIdle();
   1510 
   1511         verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
   1512     }
   1513 
   1514     @Test
   1515     public void testOnlyAutogroupIfGroupChanged_noGroupChanged_autogroups()
   1516             throws Exception {
   1517         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group",
   1518                 false);
   1519         mNotificationManagerService.addNotification(r);
   1520         mNotificationManagerService.addEnqueuedNotification(r);
   1521 
   1522         NotificationManagerService.PostNotificationRunnable runnable =
   1523                 mNotificationManagerService.new PostNotificationRunnable(r.getKey());
   1524         runnable.run();
   1525         waitForIdle();
   1526 
   1527         verify(mGroupHelper, never()).onNotificationPosted(any(), anyBoolean());
   1528     }
   1529 
   1530     @Test
   1531     public void testNoFakeColorizedPermission() throws Exception {
   1532         when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED);
   1533         Notification.Builder nb = new Notification.Builder(mContext,
   1534                 mTestNotificationChannel.getId())
   1535                 .setContentTitle("foo")
   1536                 .setColorized(true)
   1537                 .setFlag(Notification.FLAG_CAN_COLORIZE, true)
   1538                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
   1539         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
   1540                 nb.build(), new UserHandle(mUid), null, 0);
   1541         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
   1542 
   1543         mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
   1544                 nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
   1545         waitForIdle();
   1546 
   1547         NotificationRecord posted = mNotificationManagerService.findNotificationLocked(
   1548                 PKG, null, nr.sbn.getId(), nr.sbn.getUserId());
   1549 
   1550         assertFalse(posted.getNotification().isColorized());
   1551     }
   1552 
   1553     @Test
   1554     public void testGetNotificationCountLocked() throws Exception {
   1555         for (int i = 0; i < 20; i++) {
   1556             NotificationRecord r =
   1557                     generateNotificationRecord(mTestNotificationChannel, i, null, false);
   1558             mNotificationManagerService.addEnqueuedNotification(r);
   1559         }
   1560         for (int i = 0; i < 20; i++) {
   1561             NotificationRecord r =
   1562                     generateNotificationRecord(mTestNotificationChannel, i, null, false);
   1563             mNotificationManagerService.addNotification(r);
   1564         }
   1565 
   1566         // another package
   1567         Notification n =
   1568                 new Notification.Builder(mContext, mTestNotificationChannel.getId())
   1569                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
   1570                 .build();
   1571 
   1572         StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "tag", mUid, 0,
   1573                 n, new UserHandle(mUid), null, 0);
   1574         NotificationRecord otherPackage =
   1575                 new NotificationRecord(mContext, sbn, mTestNotificationChannel);
   1576         mNotificationManagerService.addEnqueuedNotification(otherPackage);
   1577         mNotificationManagerService.addNotification(otherPackage);
   1578 
   1579         // Same notifications are enqueued as posted, everything counts b/c id and tag don't match
   1580         int userId = new UserHandle(mUid).getIdentifier();
   1581         assertEquals(40,
   1582                 mNotificationManagerService.getNotificationCountLocked(PKG, userId, 0, null));
   1583         assertEquals(40,
   1584                 mNotificationManagerService.getNotificationCountLocked(PKG, userId, 0, "tag2"));
   1585         assertEquals(2,
   1586                 mNotificationManagerService.getNotificationCountLocked("a", userId, 0, "banana"));
   1587 
   1588         // exclude a known notification - it's excluded from only the posted list, not enqueued
   1589         assertEquals(39,
   1590                 mNotificationManagerService.getNotificationCountLocked(PKG, userId, 0, "tag"));
   1591     }
   1592 
   1593     @Test
   1594     public void testAddAutogroup_requestsSort() throws Exception {
   1595         RankingHandler rh = mock(RankingHandler.class);
   1596         mNotificationManagerService.setRankingHandler(rh);
   1597 
   1598         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   1599         mNotificationManagerService.addNotification(r);
   1600         mNotificationManagerService.addAutogroupKeyLocked(r.getKey());
   1601 
   1602         verify(rh, times(1)).requestSort();
   1603     }
   1604 
   1605     @Test
   1606     public void testRemoveAutogroup_requestsSort() throws Exception {
   1607         RankingHandler rh = mock(RankingHandler.class);
   1608         mNotificationManagerService.setRankingHandler(rh);
   1609 
   1610         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   1611         r.setOverrideGroupKey("TEST");
   1612         mNotificationManagerService.addNotification(r);
   1613         mNotificationManagerService.removeAutogroupKeyLocked(r.getKey());
   1614 
   1615         verify(rh, times(1)).requestSort();
   1616     }
   1617 
   1618     @Test
   1619     public void testReaddAutogroup_noSort() throws Exception {
   1620         RankingHandler rh = mock(RankingHandler.class);
   1621         mNotificationManagerService.setRankingHandler(rh);
   1622 
   1623         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   1624         r.setOverrideGroupKey("TEST");
   1625         mNotificationManagerService.addNotification(r);
   1626         mNotificationManagerService.addAutogroupKeyLocked(r.getKey());
   1627 
   1628         verify(rh, never()).requestSort();
   1629     }
   1630 
   1631     @Test
   1632     public void testHandleRankingSort_sendsUpdateOnSignalExtractorChange() throws Exception {
   1633         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1634         NotificationManagerService.WorkerHandler handler = mock(
   1635                 NotificationManagerService.WorkerHandler.class);
   1636         mNotificationManagerService.setHandler(handler);
   1637 
   1638         Map<String, Answer> answers = getSignalExtractorSideEffects();
   1639         for (String message : answers.keySet()) {
   1640             mNotificationManagerService.clearNotifications();
   1641             final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   1642             mNotificationManagerService.addNotification(r);
   1643 
   1644             doAnswer(answers.get(message)).when(mRankingHelper).extractSignals(r);
   1645 
   1646             mNotificationManagerService.handleRankingSort();
   1647         }
   1648         verify(handler, times(answers.size())).scheduleSendRankingUpdate();
   1649     }
   1650 
   1651     @Test
   1652     public void testHandleRankingSort_noUpdateWhenNoSignalChange() throws Exception {
   1653         mNotificationManagerService.setRankingHelper(mRankingHelper);
   1654         NotificationManagerService.WorkerHandler handler = mock(
   1655                 NotificationManagerService.WorkerHandler.class);
   1656         mNotificationManagerService.setHandler(handler);
   1657 
   1658         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   1659         mNotificationManagerService.addNotification(r);
   1660 
   1661         mNotificationManagerService.handleRankingSort();
   1662         verify(handler, never()).scheduleSendRankingUpdate();
   1663     }
   1664 
   1665     @Test
   1666     public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception {
   1667         final String preupgradeXml = "<notification-policy version=\"1\">"
   1668                 + "<zen></zen>"
   1669                 + "<ranking></ranking>"
   1670                 + "<enabled_listeners>"
   1671                 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
   1672                 + "</enabled_listeners>"
   1673                 + "<enabled_assistants>"
   1674                 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
   1675                 + "</enabled_assistants>"
   1676                 + "<dnd_apps>"
   1677                 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
   1678                 + "</dnd_apps>"
   1679                 + "</notification-policy>";
   1680         mNotificationManagerService.readPolicyXml(
   1681                 new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
   1682         verify(mListeners, times(1)).readXml(any());
   1683         verify(mConditionProviders, times(1)).readXml(any());
   1684         verify(mAssistants, times(1)).readXml(any());
   1685 
   1686         // numbers are inflated for setup
   1687         verify(mListeners, times(1)).migrateToXml();
   1688         verify(mConditionProviders, times(1)).migrateToXml();
   1689         verify(mAssistants, times(1)).migrateToXml();
   1690     }
   1691 
   1692     @Test
   1693     public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception {
   1694         final String preupgradeXml = "<notification-policy version=\"1\">"
   1695                 + "<zen></zen>"
   1696                 + "<ranking></ranking>"
   1697                 + "</notification-policy>";
   1698         mNotificationManagerService.readPolicyXml(
   1699                 new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
   1700         verify(mListeners, never()).readXml(any());
   1701         verify(mConditionProviders, never()).readXml(any());
   1702         verify(mAssistants, never()).readXml(any());
   1703 
   1704         // numbers are inflated for setup
   1705         verify(mListeners, times(2)).migrateToXml();
   1706         verify(mConditionProviders, times(2)).migrateToXml();
   1707         verify(mAssistants, times(2)).migrateToXml();
   1708     }
   1709 
   1710 
   1711     @Test
   1712     public void testLocaleChangedCallsUpdateDefaultZenModeRules() throws Exception {
   1713         ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
   1714         mNotificationManagerService.mZenModeHelper = mZenModeHelper;
   1715         mNotificationManagerService.mLocaleChangeReceiver.onReceive(mContext,
   1716                 new Intent(Intent.ACTION_LOCALE_CHANGED));
   1717 
   1718         verify(mZenModeHelper, times(1)).updateDefaultZenRules();
   1719     }
   1720 
   1721     @Test
   1722     public void testBumpFGImportance_noChannelChangePreOApp() throws Exception {
   1723         String preOPkg = "preO";
   1724         int preOUid = 145;
   1725         final ApplicationInfo legacy = new ApplicationInfo();
   1726         legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
   1727         when(mPackageManagerClient.getApplicationInfoAsUser(eq(preOPkg), anyInt(), anyInt()))
   1728                 .thenReturn(legacy);
   1729         when(mPackageManagerClient.getPackageUidAsUser(eq(preOPkg), anyInt())).thenReturn(preOUid);
   1730         getContext().setMockPackageManager(mPackageManagerClient);
   1731 
   1732         Notification.Builder nb = new Notification.Builder(mContext,
   1733                 NotificationChannel.DEFAULT_CHANNEL_ID)
   1734                 .setContentTitle("foo")
   1735                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
   1736                 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
   1737                 .setPriority(Notification.PRIORITY_MIN);
   1738 
   1739         StatusBarNotification sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid,
   1740                 0, nb.build(), new UserHandle(preOUid), null, 0);
   1741 
   1742         mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag",
   1743                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
   1744         waitForIdle();
   1745         assertEquals(IMPORTANCE_LOW,
   1746                 mNotificationManagerService.getNotificationRecord(sbn.getKey()).getImportance());
   1747 
   1748         nb = new Notification.Builder(mContext)
   1749                 .setContentTitle("foo")
   1750                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
   1751                 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
   1752                 .setPriority(Notification.PRIORITY_MIN);
   1753 
   1754         sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid,
   1755                 0, nb.build(), new UserHandle(preOUid), null, 0);
   1756 
   1757         mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag",
   1758                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
   1759         waitForIdle();
   1760         assertEquals(IMPORTANCE_LOW,
   1761                 mNotificationManagerService.getNotificationRecord(sbn.getKey()).getImportance());
   1762 
   1763         NotificationChannel defaultChannel = mBinderService.getNotificationChannel(
   1764                 preOPkg, NotificationChannel.DEFAULT_CHANNEL_ID);
   1765         assertEquals(IMPORTANCE_UNSPECIFIED, defaultChannel.getImportance());
   1766     }
   1767 }
   1768