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.Notification.FLAG_FOREGROUND_SERVICE;
     20 import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
     21 import static android.app.NotificationManager.IMPORTANCE_HIGH;
     22 import static android.app.NotificationManager.IMPORTANCE_LOW;
     23 import static android.app.NotificationManager.IMPORTANCE_MAX;
     24 import static android.app.NotificationManager.IMPORTANCE_NONE;
     25 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
     26 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
     27 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
     28 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
     29 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
     30 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
     31 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
     32 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
     33 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
     34 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
     35 import static android.content.pm.PackageManager.FEATURE_WATCH;
     36 import static android.content.pm.PackageManager.PERMISSION_DENIED;
     37 import static android.os.Build.VERSION_CODES.O_MR1;
     38 import static android.os.Build.VERSION_CODES.P;
     39 
     40 import static junit.framework.Assert.assertEquals;
     41 import static junit.framework.Assert.assertFalse;
     42 import static junit.framework.Assert.assertNotNull;
     43 import static junit.framework.Assert.assertNull;
     44 import static junit.framework.Assert.assertTrue;
     45 import static junit.framework.Assert.fail;
     46 
     47 import static org.mockito.Matchers.anyBoolean;
     48 import static org.mockito.Matchers.anyLong;
     49 import static org.mockito.Matchers.anyString;
     50 import static org.mockito.Matchers.eq;
     51 import static org.mockito.Mockito.any;
     52 import static org.mockito.Mockito.anyInt;
     53 import static org.mockito.Mockito.atLeastOnce;
     54 import static org.mockito.Mockito.doAnswer;
     55 import static org.mockito.Mockito.mock;
     56 import static org.mockito.Mockito.never;
     57 import static org.mockito.Mockito.reset;
     58 import static org.mockito.Mockito.spy;
     59 import static org.mockito.Mockito.timeout;
     60 import static org.mockito.Mockito.times;
     61 import static org.mockito.Mockito.verify;
     62 import static org.mockito.Mockito.when;
     63 
     64 import android.app.ActivityManager;
     65 import android.app.IActivityManager;
     66 import android.app.INotificationManager;
     67 import android.app.Notification;
     68 import android.app.Notification.MessagingStyle.Message;
     69 import android.app.NotificationChannel;
     70 import android.app.NotificationChannelGroup;
     71 import android.app.NotificationManager;
     72 import android.app.admin.DeviceAdminInfo;
     73 import android.app.admin.DevicePolicyManagerInternal;
     74 import android.app.usage.UsageStatsManagerInternal;
     75 import android.companion.ICompanionDeviceManager;
     76 import android.content.ComponentName;
     77 import android.content.ContentUris;
     78 import android.content.Context;
     79 import android.content.Intent;
     80 import android.content.pm.ApplicationInfo;
     81 import android.content.pm.IPackageManager;
     82 import android.content.pm.PackageManager;
     83 import android.content.pm.ParceledListSlice;
     84 import android.content.res.Resources;
     85 import android.graphics.Color;
     86 import android.media.AudioAttributes;
     87 import android.media.AudioManager;
     88 import android.net.Uri;
     89 import android.os.Binder;
     90 import android.os.Build;
     91 import android.os.Bundle;
     92 import android.os.IBinder;
     93 import android.os.Process;
     94 import android.os.RemoteException;
     95 import android.os.UserHandle;
     96 import android.provider.MediaStore;
     97 import android.provider.Settings.Secure;
     98 import android.service.notification.Adjustment;
     99 import android.service.notification.INotificationListener;
    100 import android.service.notification.NotificationListenerService;
    101 import android.service.notification.NotificationStats;
    102 import android.service.notification.NotifyingApp;
    103 import android.service.notification.StatusBarNotification;
    104 import android.test.suitebuilder.annotation.SmallTest;
    105 import android.testing.AndroidTestingRunner;
    106 import android.testing.TestableContext;
    107 import android.testing.TestableLooper;
    108 import android.testing.TestableLooper.RunWithLooper;
    109 import android.text.Html;
    110 import android.util.ArrayMap;
    111 import android.util.AtomicFile;
    112 
    113 import com.android.internal.R;
    114 import com.android.internal.statusbar.NotificationVisibility;
    115 import com.android.server.UiServiceTestCase;
    116 import com.android.server.lights.Light;
    117 import com.android.server.lights.LightsManager;
    118 import com.android.server.notification.NotificationManagerService.NotificationAssistants;
    119 import com.android.server.notification.NotificationManagerService.NotificationListeners;
    120 
    121 import org.junit.After;
    122 import org.junit.Before;
    123 import org.junit.Test;
    124 import org.junit.runner.RunWith;
    125 import org.mockito.ArgumentCaptor;
    126 import org.mockito.Mock;
    127 import org.mockito.MockitoAnnotations;
    128 import org.mockito.stubbing.Answer;
    129 
    130 import java.io.BufferedInputStream;
    131 import java.io.ByteArrayInputStream;
    132 import java.io.File;
    133 import java.io.FileInputStream;
    134 import java.io.FileOutputStream;
    135 import java.util.ArrayList;
    136 import java.util.Arrays;
    137 import java.util.HashSet;
    138 import java.util.List;
    139 import java.util.Map;
    140 import java.util.Set;
    141 
    142 @SmallTest
    143 @RunWith(AndroidTestingRunner.class)
    144 @RunWithLooper
    145 public class NotificationManagerServiceTest extends UiServiceTestCase {
    146     private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
    147     private final int mUid = Binder.getCallingUid();
    148     private TestableNotificationManagerService mService;
    149     private INotificationManager mBinderService;
    150     private NotificationManagerInternal mInternalService;
    151     @Mock
    152     private IPackageManager mPackageManager;
    153     @Mock
    154     private PackageManager mPackageManagerClient;
    155     private TestableContext mContext = spy(getContext());
    156     private final String PKG = mContext.getPackageName();
    157     private TestableLooper mTestableLooper;
    158     @Mock
    159     private RankingHelper mRankingHelper;
    160     AtomicFile mPolicyFile;
    161     File mFile;
    162     @Mock
    163     private NotificationUsageStats mUsageStats;
    164     @Mock
    165     private UsageStatsManagerInternal mAppUsageStats;
    166     @Mock
    167     private AudioManager mAudioManager;
    168     @Mock
    169     ActivityManager mActivityManager;
    170     NotificationManagerService.WorkerHandler mHandler;
    171     @Mock
    172     Resources mResources;
    173 
    174     private NotificationChannel mTestNotificationChannel = new NotificationChannel(
    175             TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
    176     @Mock
    177     private NotificationListeners mListeners;
    178     @Mock private NotificationAssistants mAssistants;
    179     @Mock private ConditionProviders mConditionProviders;
    180     private ManagedServices.ManagedServiceInfo mListener;
    181     @Mock private ICompanionDeviceManager mCompanionMgr;
    182     @Mock SnoozeHelper mSnoozeHelper;
    183     @Mock GroupHelper mGroupHelper;
    184     @Mock
    185     IBinder mPermOwner;
    186     @Mock
    187     IActivityManager mAm;
    188 
    189     // Use a Testable subclass so we can simulate calls from the system without failing.
    190     private static class TestableNotificationManagerService extends NotificationManagerService {
    191         int countSystemChecks = 0;
    192 
    193         public TestableNotificationManagerService(Context context) {
    194             super(context);
    195         }
    196 
    197         @Override
    198         protected boolean isCallingUidSystem() {
    199             countSystemChecks++;
    200             return true;
    201         }
    202 
    203         @Override
    204         protected boolean isCallerSystemOrPhone() {
    205             countSystemChecks++;
    206             return true;
    207         }
    208 
    209         @Override
    210         protected ICompanionDeviceManager getCompanionManager() {
    211             return null;
    212         }
    213 
    214         @Override
    215         protected void reportSeen(NotificationRecord r) {
    216             return;
    217         }
    218 
    219         @Override
    220         protected void reportUserInteraction(NotificationRecord r) {
    221             return;
    222         }
    223     }
    224 
    225     @Before
    226     public void setUp() throws Exception {
    227         MockitoAnnotations.initMocks(this);
    228 
    229         // most tests assume badging is enabled
    230         Secure.putIntForUser(getContext().getContentResolver(),
    231                 Secure.NOTIFICATION_BADGING, 1,
    232                 UserHandle.getUserHandleForUid(mUid).getIdentifier());
    233 
    234         mService = new TestableNotificationManagerService(mContext);
    235 
    236         // Use this testable looper.
    237         mTestableLooper = TestableLooper.get(this);
    238         mHandler = mService.new WorkerHandler(mTestableLooper.getLooper());
    239         // MockPackageManager - default returns ApplicationInfo with matching calling UID
    240         mContext.setMockPackageManager(mPackageManagerClient);
    241         final ApplicationInfo applicationInfo = new ApplicationInfo();
    242         applicationInfo.uid = mUid;
    243         when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
    244                 .thenReturn(applicationInfo);
    245         when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
    246                 .thenReturn(applicationInfo);
    247         when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid);
    248         final LightsManager mockLightsManager = mock(LightsManager.class);
    249         when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
    250         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
    251         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
    252         when(mAm.newUriPermissionOwner(anyString())).thenReturn(mPermOwner);
    253 
    254         // write to a test file; the system file isn't readable from tests
    255         mFile = new File(mContext.getCacheDir(), "test.xml");
    256         mFile.createNewFile();
    257         final String preupgradeXml = "<notification-policy></notification-policy>";
    258         mPolicyFile = new AtomicFile(mFile);
    259         FileOutputStream fos = mPolicyFile.startWrite();
    260         fos.write(preupgradeXml.getBytes());
    261         mPolicyFile.finishWrite(fos);
    262         FileInputStream fStream = new FileInputStream(mFile);
    263 
    264         // Setup managed services
    265         mListener = mListeners.new ManagedServiceInfo(
    266                 null, new ComponentName(PKG, "test_class"), mUid, true, null, 0);
    267         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
    268         ManagedServices.Config listenerConfig = new ManagedServices.Config();
    269         listenerConfig.xmlTag = NotificationListeners.TAG_ENABLED_NOTIFICATION_LISTENERS;
    270         when(mListeners.getConfig()).thenReturn(listenerConfig);
    271         ManagedServices.Config assistantConfig = new ManagedServices.Config();
    272         assistantConfig.xmlTag = NotificationAssistants.TAG_ENABLED_NOTIFICATION_ASSISTANTS;
    273         when(mAssistants.getConfig()).thenReturn(assistantConfig);
    274         ManagedServices.Config dndConfig = new ManagedServices.Config();
    275         dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS;
    276         when(mConditionProviders.getConfig()).thenReturn(dndConfig);
    277 
    278         try {
    279             mService.init(mTestableLooper.getLooper(),
    280                     mPackageManager, mPackageManagerClient, mockLightsManager,
    281                     mListeners, mAssistants, mConditionProviders,
    282                     mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
    283                     mGroupHelper, mAm, mAppUsageStats,
    284                     mock(DevicePolicyManagerInternal.class));
    285         } catch (SecurityException e) {
    286             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
    287                 throw e;
    288             }
    289         }
    290         mService.setAudioManager(mAudioManager);
    291 
    292         // Tests call directly into the Binder.
    293         mBinderService = mService.getBinderService();
    294         mInternalService = mService.getInternalService();
    295 
    296         mBinderService.createNotificationChannels(
    297                 PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel)));
    298         assertNotNull(mBinderService.getNotificationChannel(PKG, TEST_CHANNEL_ID));
    299     }
    300 
    301     @After
    302     public void tearDown() throws Exception {
    303         mFile.delete();
    304     }
    305 
    306     public void waitForIdle() {
    307         mTestableLooper.processAllMessages();
    308     }
    309 
    310     private StatusBarNotification generateSbn(String pkg, int uid, long postTime, int userId) {
    311         Notification.Builder nb = new Notification.Builder(mContext, "a")
    312                 .setContentTitle("foo")
    313                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
    314         StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, uid, "tag", uid, 0,
    315                 nb.build(), new UserHandle(userId), null, postTime);
    316         return sbn;
    317     }
    318 
    319     private NotificationRecord generateNotificationRecord(NotificationChannel channel, int id,
    320             String groupKey, boolean isSummary) {
    321         Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
    322                 .setContentTitle("foo")
    323                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
    324                 .setGroup(groupKey)
    325                 .setGroupSummary(isSummary);
    326 
    327         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
    328                 nb.build(), new UserHandle(mUid), null, 0);
    329         return new NotificationRecord(mContext, sbn, channel);
    330     }
    331 
    332     private NotificationRecord generateNotificationRecord(NotificationChannel channel) {
    333         return generateNotificationRecord(channel, null);
    334     }
    335 
    336     private NotificationRecord generateNotificationRecord(NotificationChannel channel,
    337             Notification.TvExtender extender) {
    338         if (channel == null) {
    339             channel = mTestNotificationChannel;
    340         }
    341         Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
    342                 .setContentTitle("foo")
    343                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
    344         if (extender != null) {
    345             nb.extend(extender);
    346         }
    347         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
    348                 nb.build(), new UserHandle(mUid), null, 0);
    349         return new NotificationRecord(mContext, sbn, channel);
    350     }
    351 
    352     private Map<String, Answer> getSignalExtractorSideEffects() {
    353         Map<String, Answer> answers = new ArrayMap<>();
    354 
    355         answers.put("override group key", invocationOnMock -> {
    356             ((NotificationRecord) invocationOnMock.getArguments()[0])
    357                     .setOverrideGroupKey("bananas");
    358             return null;
    359         });
    360         answers.put("override people", invocationOnMock -> {
    361             ((NotificationRecord) invocationOnMock.getArguments()[0])
    362                     .setPeopleOverride(new ArrayList<>());
    363             return null;
    364         });
    365         answers.put("snooze criteria", invocationOnMock -> {
    366             ((NotificationRecord) invocationOnMock.getArguments()[0])
    367                     .setSnoozeCriteria(new ArrayList<>());
    368             return null;
    369         });
    370         answers.put("notification channel", invocationOnMock -> {
    371             ((NotificationRecord) invocationOnMock.getArguments()[0])
    372                     .updateNotificationChannel(new NotificationChannel("a", "", IMPORTANCE_LOW));
    373             return null;
    374         });
    375         answers.put("badging", invocationOnMock -> {
    376             NotificationRecord r = (NotificationRecord) invocationOnMock.getArguments()[0];
    377             r.setShowBadge(!r.canShowBadge());
    378             return null;
    379         });
    380         answers.put("package visibility", invocationOnMock -> {
    381             ((NotificationRecord) invocationOnMock.getArguments()[0]).setPackageVisibilityOverride(
    382                     Notification.VISIBILITY_SECRET);
    383             return null;
    384         });
    385 
    386         return answers;
    387     }
    388 
    389     @Test
    390     public void testCreateNotificationChannels_SingleChannel() throws Exception {
    391         final NotificationChannel channel =
    392                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
    393         mBinderService.createNotificationChannels(PKG,
    394                 new ParceledListSlice(Arrays.asList(channel)));
    395         final NotificationChannel createdChannel =
    396                 mBinderService.getNotificationChannel(PKG, "id");
    397         assertTrue(createdChannel != null);
    398     }
    399 
    400     @Test
    401     public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception {
    402         try {
    403             mBinderService.createNotificationChannels(PKG,
    404                     new ParceledListSlice(Arrays.asList((Object[])null)));
    405             fail("Exception should be thrown immediately.");
    406         } catch (NullPointerException e) {
    407             // pass
    408         }
    409     }
    410 
    411     @Test
    412     public void testCreateNotificationChannels_TwoChannels() throws Exception {
    413         final NotificationChannel channel1 =
    414                 new NotificationChannel("id1", "name", NotificationManager.IMPORTANCE_DEFAULT);
    415         final NotificationChannel channel2 =
    416                 new NotificationChannel("id2", "name", NotificationManager.IMPORTANCE_DEFAULT);
    417         mBinderService.createNotificationChannels(PKG,
    418                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
    419         assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null);
    420         assertTrue(mBinderService.getNotificationChannel(PKG, "id2") != null);
    421     }
    422 
    423     @Test
    424     public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance()
    425             throws Exception {
    426         final NotificationChannel channel =
    427                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
    428         mBinderService.createNotificationChannels(PKG,
    429                 new ParceledListSlice(Arrays.asList(channel)));
    430 
    431         // Recreating the channel doesn't throw, but ignores importance.
    432         final NotificationChannel dupeChannel =
    433                 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
    434         mBinderService.createNotificationChannels(PKG,
    435                 new ParceledListSlice(Arrays.asList(dupeChannel)));
    436         final NotificationChannel createdChannel =
    437                 mBinderService.getNotificationChannel(PKG, "id");
    438         assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
    439     }
    440 
    441     @Test
    442     public void testCreateNotificationChannels_SecondCreateAllowedToDowngradeImportance()
    443             throws Exception {
    444         final NotificationChannel channel =
    445                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
    446         mBinderService.createNotificationChannels(PKG,
    447                 new ParceledListSlice(Arrays.asList(channel)));
    448 
    449         // Recreating with a lower importance is allowed to modify the channel.
    450         final NotificationChannel dupeChannel =
    451                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
    452         mBinderService.createNotificationChannels(PKG,
    453                 new ParceledListSlice(Arrays.asList(dupeChannel)));
    454         final NotificationChannel createdChannel =
    455                 mBinderService.getNotificationChannel(PKG, "id");
    456         assertEquals(NotificationManager.IMPORTANCE_LOW, createdChannel.getImportance());
    457     }
    458 
    459     @Test
    460     public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated()
    461             throws Exception {
    462         final NotificationChannel channel =
    463                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
    464         mBinderService.createNotificationChannels(PKG,
    465                 new ParceledListSlice(Arrays.asList(channel)));
    466 
    467         // The user modifies importance directly, can no longer be changed by the app.
    468         final NotificationChannel updatedChannel =
    469                 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
    470         mBinderService.updateNotificationChannelForPackage(PKG, mUid, updatedChannel);
    471 
    472         // Recreating with a lower importance leaves channel unchanged.
    473         final NotificationChannel dupeChannel =
    474                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
    475         mBinderService.createNotificationChannels(PKG,
    476                 new ParceledListSlice(Arrays.asList(dupeChannel)));
    477         final NotificationChannel createdChannel =
    478                 mBinderService.getNotificationChannel(PKG, "id");
    479         assertEquals(IMPORTANCE_HIGH, createdChannel.getImportance());
    480     }
    481 
    482     @Test
    483     public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond()
    484             throws Exception {
    485         final NotificationChannel channel1 =
    486                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
    487         final NotificationChannel channel2 =
    488                 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
    489         mBinderService.createNotificationChannels(PKG,
    490                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
    491         final NotificationChannel createdChannel =
    492                 mBinderService.getNotificationChannel(PKG, "id");
    493         assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
    494     }
    495 
    496     @Test
    497     public void testBlockedNotifications_suspended() throws Exception {
    498         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(true);
    499 
    500         NotificationChannel channel = new NotificationChannel("id", "name",
    501                 IMPORTANCE_HIGH);
    502         NotificationRecord r = generateNotificationRecord(channel);
    503         assertTrue(mService.isBlocked(r, mUsageStats));
    504         verify(mUsageStats, times(1)).registerSuspendedByAdmin(eq(r));
    505     }
    506 
    507     @Test
    508     public void testBlockedNotifications_blockedChannel() throws Exception {
    509         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    510 
    511         NotificationChannel channel = new NotificationChannel("id", "name",
    512                 NotificationManager.IMPORTANCE_NONE);
    513         NotificationRecord r = generateNotificationRecord(channel);
    514         assertTrue(mService.isBlocked(r, mUsageStats));
    515         verify(mUsageStats, times(1)).registerBlocked(eq(r));
    516 
    517         mBinderService.createNotificationChannels(
    518                 PKG, new ParceledListSlice(Arrays.asList(channel)));
    519         final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
    520         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    521                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    522         waitForIdle();
    523         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    524     }
    525 
    526     @Test
    527     public void testEnqueuedBlockedNotifications_appBlockedChannelForegroundService()
    528             throws Exception {
    529         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    530 
    531         NotificationChannel channel = new NotificationChannel("blocked", "name",
    532                 NotificationManager.IMPORTANCE_NONE);
    533         mBinderService.createNotificationChannels(
    534                 PKG, new ParceledListSlice(Arrays.asList(channel)));
    535 
    536         final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
    537         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
    538         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    539                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    540         waitForIdle();
    541         assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    542         assertEquals(IMPORTANCE_LOW,
    543                 mService.getNotificationRecord(sbn.getKey()).getImportance());
    544         assertEquals(IMPORTANCE_LOW,
    545                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
    546     }
    547 
    548     @Test
    549     public void testEnqueuedBlockedNotifications_userBlockedChannelForegroundService()
    550             throws Exception {
    551         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    552 
    553         NotificationChannel channel =
    554                 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_HIGH);
    555         mBinderService.createNotificationChannels(
    556                 PKG, new ParceledListSlice(Arrays.asList(channel)));
    557 
    558         NotificationChannel update =
    559                 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
    560         mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
    561         waitForIdle();
    562         assertEquals(IMPORTANCE_NONE,
    563                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
    564 
    565         StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
    566         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
    567         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    568                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    569         waitForIdle();
    570         // The first time a foreground service notification is shown, we allow the channel
    571         // to be updated to allow it to be seen.
    572         assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    573         assertEquals(IMPORTANCE_LOW,
    574                 mService.getNotificationRecord(sbn.getKey()).getImportance());
    575         assertEquals(IMPORTANCE_LOW,
    576                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
    577         mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
    578         waitForIdle();
    579 
    580         update = new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
    581         update.setFgServiceShown(true);
    582         mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
    583         waitForIdle();
    584         assertEquals(IMPORTANCE_NONE,
    585                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
    586 
    587         sbn = generateNotificationRecord(channel).sbn;
    588         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
    589         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    590                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    591         waitForIdle();
    592         // The second time it is shown, we keep the user's preference.
    593         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    594         assertNull(mService.getNotificationRecord(sbn.getKey()));
    595         assertEquals(IMPORTANCE_NONE,
    596                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
    597     }
    598 
    599     @Test
    600     public void testBlockedNotifications_blockedChannelGroup() throws Exception {
    601         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    602         mService.setRankingHelper(mRankingHelper);
    603         when(mRankingHelper.isGroupBlocked(anyString(), anyInt(), anyString())).thenReturn(true);
    604 
    605         NotificationChannel channel = new NotificationChannel("id", "name",
    606                 NotificationManager.IMPORTANCE_HIGH);
    607         channel.setGroup("something");
    608         NotificationRecord r = generateNotificationRecord(channel);
    609         assertTrue(mService.isBlocked(r, mUsageStats));
    610         verify(mUsageStats, times(1)).registerBlocked(eq(r));
    611     }
    612 
    613     @Test
    614     public void testEnqueuedBlockedNotifications_blockedApp() throws Exception {
    615         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    616 
    617         mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
    618 
    619         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    620         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    621                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    622         waitForIdle();
    623         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    624     }
    625 
    626     @Test
    627     public void testEnqueuedBlockedNotifications_blockedAppForegroundService() throws Exception {
    628         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
    629 
    630         mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
    631 
    632         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    633         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
    634         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    635                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    636         waitForIdle();
    637         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    638         assertNull(mService.getNotificationRecord(sbn.getKey()));
    639     }
    640 
    641     @Test
    642     public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
    643         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
    644                 generateNotificationRecord(null).getNotification(), 0);
    645         waitForIdle();
    646         StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
    647         assertEquals(1, notifs.length);
    648         assertEquals(1, mService.getNotificationRecordCount());
    649     }
    650 
    651     @Test
    652     public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
    653         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
    654                 generateNotificationRecord(null).getNotification(), 0);
    655         mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
    656         waitForIdle();
    657         StatusBarNotification[] notifs =
    658                 mBinderService.getActiveNotifications(PKG);
    659         assertEquals(0, notifs.length);
    660         assertEquals(0, mService.getNotificationRecordCount());
    661     }
    662 
    663     @Test
    664     public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
    665         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
    666                 generateNotificationRecord(null).getNotification(), 0);
    667         waitForIdle();
    668         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
    669                 generateNotificationRecord(null).getNotification(), 0);
    670         mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
    671         waitForIdle();
    672         StatusBarNotification[] notifs =
    673                 mBinderService.getActiveNotifications(PKG);
    674         assertEquals(0, notifs.length);
    675         assertEquals(0, mService.getNotificationRecordCount());
    676         ArgumentCaptor<NotificationStats> captor = ArgumentCaptor.forClass(NotificationStats.class);
    677         verify(mListeners, times(1)).notifyRemovedLocked(any(), anyInt(), captor.capture());
    678         assertEquals(NotificationStats.DISMISSAL_OTHER, captor.getValue().getDismissalSurface());
    679     }
    680 
    681     @Test
    682     public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
    683         NotificationRecord r = generateNotificationRecord(null);
    684         final StatusBarNotification sbn = r.sbn;
    685         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    686                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    687         mBinderService.cancelNotificationsFromListener(null, null);
    688         waitForIdle();
    689         StatusBarNotification[] notifs =
    690                 mBinderService.getActiveNotifications(sbn.getPackageName());
    691         assertEquals(0, notifs.length);
    692         assertEquals(0, mService.getNotificationRecordCount());
    693     }
    694 
    695     @Test
    696     public void testCancelAllNotificationsImmediatelyAfterEnqueue() 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(PKG, sbn.getUserId());
    701         waitForIdle();
    702         StatusBarNotification[] notifs =
    703                 mBinderService.getActiveNotifications(sbn.getPackageName());
    704         assertEquals(0, notifs.length);
    705         assertEquals(0, mService.getNotificationRecordCount());
    706     }
    707 
    708     @Test
    709     public void testUserInitiatedClearAll_noLeak() throws Exception {
    710         final NotificationRecord n = generateNotificationRecord(
    711                 mTestNotificationChannel, 1, "group", true);
    712 
    713         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    714                 n.sbn.getId(), n.sbn.getNotification(), n.sbn.getUserId());
    715         waitForIdle();
    716 
    717         mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
    718                 n.getUserId());
    719         waitForIdle();
    720         StatusBarNotification[] notifs =
    721                 mBinderService.getActiveNotifications(n.sbn.getPackageName());
    722         assertEquals(0, notifs.length);
    723         assertEquals(0, mService.getNotificationRecordCount());
    724         ArgumentCaptor<NotificationStats> captor = ArgumentCaptor.forClass(NotificationStats.class);
    725         verify(mListeners, times(1)).notifyRemovedLocked(any(), anyInt(), captor.capture());
    726         assertEquals(NotificationStats.DISMISSAL_OTHER, captor.getValue().getDismissalSurface());
    727     }
    728 
    729     @Test
    730     public void testCancelAllNotificationsCancelsChildren() throws Exception {
    731         final NotificationRecord parent = generateNotificationRecord(
    732                 mTestNotificationChannel, 1, "group1", true);
    733         final NotificationRecord child = generateNotificationRecord(
    734                 mTestNotificationChannel, 2, "group1", false);
    735 
    736         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    737                 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
    738         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    739                 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
    740         waitForIdle();
    741 
    742         mBinderService.cancelAllNotifications(PKG, parent.sbn.getUserId());
    743         waitForIdle();
    744         assertEquals(0, mService.getNotificationRecordCount());
    745     }
    746 
    747     @Test
    748     public void testCancelAllNotificationsMultipleEnqueuedDoesNotCrash() throws Exception {
    749         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    750         for (int i = 0; i < 10; i++) {
    751             mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    752                     sbn.getId(), sbn.getNotification(), sbn.getUserId());
    753         }
    754         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
    755         waitForIdle();
    756 
    757         assertEquals(0, mService.getNotificationRecordCount());
    758     }
    759 
    760     @Test
    761     public void testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash() throws Exception {
    762         final NotificationRecord parent = generateNotificationRecord(
    763                 mTestNotificationChannel, 1, "group1", true);
    764         final NotificationRecord parentAsChild = generateNotificationRecord(
    765                 mTestNotificationChannel, 1, "group1", false);
    766         final NotificationRecord child = generateNotificationRecord(
    767                 mTestNotificationChannel, 2, "group1", false);
    768 
    769         // fully post parent notification
    770         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    771                 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
    772         waitForIdle();
    773 
    774         // enqueue the child several times
    775         for (int i = 0; i < 10; i++) {
    776             mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    777                     child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
    778         }
    779         // make the parent a child, which will cancel the child notification
    780         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    781                 parentAsChild.sbn.getId(), parentAsChild.sbn.getNotification(),
    782                 parentAsChild.sbn.getUserId());
    783         waitForIdle();
    784 
    785         assertEquals(0, mService.getNotificationRecordCount());
    786     }
    787 
    788     @Test
    789     public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
    790         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    791         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
    792         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    793                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    794         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
    795         waitForIdle();
    796         StatusBarNotification[] notifs =
    797                 mBinderService.getActiveNotifications(sbn.getPackageName());
    798         assertEquals(1, notifs.length);
    799         assertEquals(1, mService.getNotificationRecordCount());
    800     }
    801 
    802     @Test
    803     public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
    804         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    805         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
    806         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    807                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    808         mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
    809         waitForIdle();
    810         StatusBarNotification[] notifs =
    811                 mBinderService.getActiveNotifications(sbn.getPackageName());
    812         assertEquals(1, notifs.length);
    813         assertEquals(1, mService.getNotificationRecordCount());
    814     }
    815 
    816     @Test
    817     public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
    818         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    819         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    820                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    821         mBinderService.cancelAllNotifications(null, sbn.getUserId());
    822         waitForIdle();
    823         StatusBarNotification[] notifs =
    824                 mBinderService.getActiveNotifications(sbn.getPackageName());
    825         assertEquals(0, notifs.length);
    826         assertEquals(0, mService.getNotificationRecordCount());
    827     }
    828 
    829     @Test
    830     public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
    831         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    832         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    833                 sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL);
    834         // Null pkg is how we signal a user switch.
    835         mBinderService.cancelAllNotifications(null, sbn.getUserId());
    836         waitForIdle();
    837         StatusBarNotification[] notifs =
    838                 mBinderService.getActiveNotifications(sbn.getPackageName());
    839         assertEquals(1, notifs.length);
    840         assertEquals(1, mService.getNotificationRecordCount());
    841     }
    842 
    843     @Test
    844     public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception {
    845         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    846         sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR;
    847         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    848                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    849         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
    850         waitForIdle();
    851         StatusBarNotification[] notifs =
    852                 mBinderService.getActiveNotifications(sbn.getPackageName());
    853         assertEquals(0, notifs.length);
    854     }
    855 
    856     @Test
    857     public void testCancelAllNotifications_CancelsNoClearFlag() throws Exception {
    858         final NotificationRecord notif = generateNotificationRecord(
    859                 mTestNotificationChannel, 1, "group", true);
    860         notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
    861         mService.addNotification(notif);
    862         mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true,
    863                 notif.getUserId(), 0, null);
    864         waitForIdle();
    865         StatusBarNotification[] notifs =
    866                 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
    867         assertEquals(0, notifs.length);
    868     }
    869 
    870     @Test
    871     public void testUserInitiatedCancelAllOnClearAll_NoClearFlag() throws Exception {
    872         final NotificationRecord notif = generateNotificationRecord(
    873                 mTestNotificationChannel, 1, "group", true);
    874         notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
    875         mService.addNotification(notif);
    876 
    877         mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
    878                 notif.getUserId());
    879         waitForIdle();
    880         StatusBarNotification[] notifs =
    881                 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
    882         assertEquals(1, notifs.length);
    883     }
    884 
    885     @Test
    886     public void testCancelAllCancelNotificationsFromListener_NoClearFlag() throws Exception {
    887         final NotificationRecord parent = generateNotificationRecord(
    888                 mTestNotificationChannel, 1, "group", true);
    889         final NotificationRecord child = generateNotificationRecord(
    890                 mTestNotificationChannel, 2, "group", false);
    891         final NotificationRecord child2 = generateNotificationRecord(
    892                 mTestNotificationChannel, 3, "group", false);
    893         child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
    894         final NotificationRecord newGroup = generateNotificationRecord(
    895                 mTestNotificationChannel, 4, "group2", false);
    896         mService.addNotification(parent);
    897         mService.addNotification(child);
    898         mService.addNotification(child2);
    899         mService.addNotification(newGroup);
    900         mService.getBinderService().cancelNotificationsFromListener(null, null);
    901         waitForIdle();
    902         StatusBarNotification[] notifs =
    903                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
    904         assertEquals(1, notifs.length);
    905     }
    906 
    907     @Test
    908     public void testUserInitiatedCancelAllWithGroup_NoClearFlag() throws Exception {
    909         final NotificationRecord parent = generateNotificationRecord(
    910                 mTestNotificationChannel, 1, "group", true);
    911         final NotificationRecord child = generateNotificationRecord(
    912                 mTestNotificationChannel, 2, "group", false);
    913         final NotificationRecord child2 = generateNotificationRecord(
    914                 mTestNotificationChannel, 3, "group", false);
    915         child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
    916         final NotificationRecord newGroup = generateNotificationRecord(
    917                 mTestNotificationChannel, 4, "group2", false);
    918         mService.addNotification(parent);
    919         mService.addNotification(child);
    920         mService.addNotification(child2);
    921         mService.addNotification(newGroup);
    922         mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
    923                 parent.getUserId());
    924         waitForIdle();
    925         StatusBarNotification[] notifs =
    926                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
    927         assertEquals(1, notifs.length);
    928     }
    929 
    930     @Test
    931     public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
    932         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    933         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
    934         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
    935                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    936         mInternalService.removeForegroundServiceFlagFromNotification(PKG, sbn.getId(),
    937                 sbn.getUserId());
    938         waitForIdle();
    939         StatusBarNotification[] notifs =
    940                 mBinderService.getActiveNotifications(sbn.getPackageName());
    941         assertEquals(0, notifs[0].getNotification().flags & FLAG_FOREGROUND_SERVICE);
    942     }
    943 
    944     @Test
    945     public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception {
    946         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
    947         sbn.getNotification().flags =
    948                 Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
    949         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    950                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    951         sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
    952         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
    953                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
    954         mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
    955         waitForIdle();
    956         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
    957         assertEquals(0, mService.getNotificationRecordCount());
    958     }
    959 
    960     @Test
    961     public void testCancelAllCancelNotificationsFromListener_ForegroundServiceFlag()
    962             throws Exception {
    963         final NotificationRecord parent = generateNotificationRecord(
    964                 mTestNotificationChannel, 1, "group", true);
    965         final NotificationRecord child = generateNotificationRecord(
    966                 mTestNotificationChannel, 2, "group", false);
    967         final NotificationRecord child2 = generateNotificationRecord(
    968                 mTestNotificationChannel, 3, "group", false);
    969         child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
    970         final NotificationRecord newGroup = generateNotificationRecord(
    971                 mTestNotificationChannel, 4, "group2", false);
    972         mService.addNotification(parent);
    973         mService.addNotification(child);
    974         mService.addNotification(child2);
    975         mService.addNotification(newGroup);
    976         mService.getBinderService().cancelNotificationsFromListener(null, null);
    977         waitForIdle();
    978         StatusBarNotification[] notifs =
    979                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
    980         assertEquals(0, notifs.length);
    981     }
    982 
    983     @Test
    984     public void testCancelAllCancelNotificationsFromListener_ForegroundServiceFlagWithParameter()
    985             throws Exception {
    986         final NotificationRecord parent = generateNotificationRecord(
    987                 mTestNotificationChannel, 1, "group", true);
    988         final NotificationRecord child = generateNotificationRecord(
    989                 mTestNotificationChannel, 2, "group", false);
    990         final NotificationRecord child2 = generateNotificationRecord(
    991                 mTestNotificationChannel, 3, "group", false);
    992         child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
    993         final NotificationRecord newGroup = generateNotificationRecord(
    994                 mTestNotificationChannel, 4, "group2", false);
    995         mService.addNotification(parent);
    996         mService.addNotification(child);
    997         mService.addNotification(child2);
    998         mService.addNotification(newGroup);
    999         String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
   1000                 child2.sbn.getKey(), newGroup.sbn.getKey()};
   1001         mService.getBinderService().cancelNotificationsFromListener(null, keys);
   1002         waitForIdle();
   1003         StatusBarNotification[] notifs =
   1004                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
   1005         assertEquals(1, notifs.length);
   1006     }
   1007 
   1008     @Test
   1009     public void testUserInitiatedCancelAllWithGroup_ForegroundServiceFlag() throws Exception {
   1010         final NotificationRecord parent = generateNotificationRecord(
   1011                 mTestNotificationChannel, 1, "group", true);
   1012         final NotificationRecord child = generateNotificationRecord(
   1013                 mTestNotificationChannel, 2, "group", false);
   1014         final NotificationRecord child2 = generateNotificationRecord(
   1015                 mTestNotificationChannel, 3, "group", false);
   1016         child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
   1017         final NotificationRecord newGroup = generateNotificationRecord(
   1018                 mTestNotificationChannel, 4, "group2", false);
   1019         mService.addNotification(parent);
   1020         mService.addNotification(child);
   1021         mService.addNotification(child2);
   1022         mService.addNotification(newGroup);
   1023         mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
   1024                 parent.getUserId());
   1025         waitForIdle();
   1026         StatusBarNotification[] notifs =
   1027                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
   1028         assertEquals(0, notifs.length);
   1029     }
   1030 
   1031     @Test
   1032     public void testFindGroupNotificationsLocked() throws Exception {
   1033         // make sure the same notification can be found in both lists and returned
   1034         final NotificationRecord group1 = generateNotificationRecord(
   1035                 mTestNotificationChannel, 1, "group1", true);
   1036         mService.addEnqueuedNotification(group1);
   1037         mService.addNotification(group1);
   1038 
   1039         // should not be returned
   1040         final NotificationRecord group2 = generateNotificationRecord(
   1041                 mTestNotificationChannel, 2, "group2", true);
   1042         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
   1043                 group2.sbn.getId(), group2.sbn.getNotification(), group2.sbn.getUserId());
   1044         waitForIdle();
   1045 
   1046         // should not be returned
   1047         final NotificationRecord nonGroup = generateNotificationRecord(
   1048                 mTestNotificationChannel, 3, null, false);
   1049         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
   1050                 nonGroup.sbn.getId(), nonGroup.sbn.getNotification(), nonGroup.sbn.getUserId());
   1051         waitForIdle();
   1052 
   1053         // same group, child, should be returned
   1054         final NotificationRecord group1Child = generateNotificationRecord(
   1055                 mTestNotificationChannel, 4, "group1", false);
   1056         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, group1Child.sbn.getId(),
   1057                 group1Child.sbn.getNotification(), group1Child.sbn.getUserId());
   1058         waitForIdle();
   1059 
   1060         List<NotificationRecord> inGroup1 =
   1061                 mService.findGroupNotificationsLocked(PKG, group1.getGroupKey(),
   1062                         group1.sbn.getUserId());
   1063         assertEquals(3, inGroup1.size());
   1064         for (NotificationRecord record : inGroup1) {
   1065             assertTrue(record.getGroupKey().equals(group1.getGroupKey()));
   1066             assertTrue(record.sbn.getId() == 1 || record.sbn.getId() == 4);
   1067         }
   1068     }
   1069 
   1070     @Test
   1071     public void testCancelAllNotifications_CancelsNoClearFlagOnGoing() throws Exception {
   1072         final NotificationRecord notif = generateNotificationRecord(
   1073                 mTestNotificationChannel, 1, "group", true);
   1074         notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
   1075         mService.addNotification(notif);
   1076         mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0,
   1077                 Notification.FLAG_ONGOING_EVENT, true, notif.getUserId(), 0, null);
   1078         waitForIdle();
   1079         StatusBarNotification[] notifs =
   1080                 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
   1081         assertEquals(0, notifs.length);
   1082     }
   1083 
   1084     @Test
   1085     public void testCancelAllCancelNotificationsFromListener_NoClearFlagWithParameter()
   1086             throws Exception {
   1087         final NotificationRecord parent = generateNotificationRecord(
   1088                 mTestNotificationChannel, 1, "group", true);
   1089         final NotificationRecord child = generateNotificationRecord(
   1090                 mTestNotificationChannel, 2, "group", false);
   1091         final NotificationRecord child2 = generateNotificationRecord(
   1092                 mTestNotificationChannel, 3, "group", false);
   1093         child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
   1094         final NotificationRecord newGroup = generateNotificationRecord(
   1095                 mTestNotificationChannel, 4, "group2", false);
   1096         mService.addNotification(parent);
   1097         mService.addNotification(child);
   1098         mService.addNotification(child2);
   1099         mService.addNotification(newGroup);
   1100         String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
   1101                 child2.sbn.getKey(), newGroup.sbn.getKey()};
   1102         mService.getBinderService().cancelNotificationsFromListener(null, keys);
   1103         waitForIdle();
   1104         StatusBarNotification[] notifs =
   1105                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
   1106         assertEquals(0, notifs.length);
   1107     }
   1108 
   1109     @Test
   1110     public void testAppInitiatedCancelAllNotifications_CancelsOnGoingFlag() throws Exception {
   1111         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
   1112         sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
   1113         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
   1114                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
   1115         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
   1116         waitForIdle();
   1117         StatusBarNotification[] notifs =
   1118                 mBinderService.getActiveNotifications(sbn.getPackageName());
   1119         assertEquals(0, notifs.length);
   1120     }
   1121 
   1122     @Test
   1123     public void testCancelAllNotifications_CancelsOnGoingFlag() throws Exception {
   1124         final NotificationRecord notif = generateNotificationRecord(
   1125                 mTestNotificationChannel, 1, "group", true);
   1126         notif.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
   1127         mService.addNotification(notif);
   1128         mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true,
   1129                 notif.getUserId(), 0, null);
   1130         waitForIdle();
   1131         StatusBarNotification[] notifs =
   1132                 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
   1133         assertEquals(0, notifs.length);
   1134     }
   1135 
   1136     @Test
   1137     public void testUserInitiatedCancelAllOnClearAll_OnGoingFlag() throws Exception {
   1138         final NotificationRecord notif = generateNotificationRecord(
   1139                 mTestNotificationChannel, 1, "group", true);
   1140         notif.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
   1141         mService.addNotification(notif);
   1142 
   1143         mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
   1144                 notif.getUserId());
   1145         waitForIdle();
   1146         StatusBarNotification[] notifs =
   1147                 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
   1148         assertEquals(1, notifs.length);
   1149     }
   1150 
   1151     @Test
   1152     public void testCancelAllCancelNotificationsFromListener_OnGoingFlag() throws Exception {
   1153         final NotificationRecord parent = generateNotificationRecord(
   1154                 mTestNotificationChannel, 1, "group", true);
   1155         final NotificationRecord child = generateNotificationRecord(
   1156                 mTestNotificationChannel, 2, "group", false);
   1157         final NotificationRecord child2 = generateNotificationRecord(
   1158                 mTestNotificationChannel, 3, "group", false);
   1159         child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
   1160         final NotificationRecord newGroup = generateNotificationRecord(
   1161                 mTestNotificationChannel, 4, "group2", false);
   1162         mService.addNotification(parent);
   1163         mService.addNotification(child);
   1164         mService.addNotification(child2);
   1165         mService.addNotification(newGroup);
   1166         mService.getBinderService().cancelNotificationsFromListener(null, null);
   1167         waitForIdle();
   1168         StatusBarNotification[] notifs =
   1169                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
   1170         assertEquals(1, notifs.length);
   1171     }
   1172 
   1173     @Test
   1174     public void testCancelAllCancelNotificationsFromListener_OnGoingFlagWithParameter()
   1175             throws Exception {
   1176         final NotificationRecord parent = generateNotificationRecord(
   1177                 mTestNotificationChannel, 1, "group", true);
   1178         final NotificationRecord child = generateNotificationRecord(
   1179                 mTestNotificationChannel, 2, "group", false);
   1180         final NotificationRecord child2 = generateNotificationRecord(
   1181                 mTestNotificationChannel, 3, "group", false);
   1182         child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
   1183         final NotificationRecord newGroup = generateNotificationRecord(
   1184                 mTestNotificationChannel, 4, "group2", false);
   1185         mService.addNotification(parent);
   1186         mService.addNotification(child);
   1187         mService.addNotification(child2);
   1188         mService.addNotification(newGroup);
   1189         String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
   1190                 child2.sbn.getKey(), newGroup.sbn.getKey()};
   1191         mService.getBinderService().cancelNotificationsFromListener(null, keys);
   1192         waitForIdle();
   1193         StatusBarNotification[] notifs =
   1194                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
   1195         assertEquals(0, notifs.length);
   1196     }
   1197 
   1198     @Test
   1199     public void testUserInitiatedCancelAllWithGroup_OnGoingFlag() throws Exception {
   1200         final NotificationRecord parent = generateNotificationRecord(
   1201                 mTestNotificationChannel, 1, "group", true);
   1202         final NotificationRecord child = generateNotificationRecord(
   1203                 mTestNotificationChannel, 2, "group", false);
   1204         final NotificationRecord child2 = generateNotificationRecord(
   1205                 mTestNotificationChannel, 3, "group", false);
   1206         child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
   1207         final NotificationRecord newGroup = generateNotificationRecord(
   1208                 mTestNotificationChannel, 4, "group2", false);
   1209         mService.addNotification(parent);
   1210         mService.addNotification(child);
   1211         mService.addNotification(child2);
   1212         mService.addNotification(newGroup);
   1213         mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
   1214                 parent.getUserId());
   1215         waitForIdle();
   1216         StatusBarNotification[] notifs =
   1217                 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
   1218         assertEquals(1, notifs.length);
   1219     }
   1220 
   1221     @Test
   1222     public void testTvExtenderChannelOverride_onTv() throws Exception {
   1223         mService.setIsTelevision(true);
   1224         mService.setRankingHelper(mRankingHelper);
   1225         when(mRankingHelper.getNotificationChannel(
   1226                 anyString(), anyInt(), eq("foo"), anyBoolean())).thenReturn(
   1227                         new NotificationChannel("foo", "foo", IMPORTANCE_HIGH));
   1228 
   1229         Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
   1230         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
   1231                 generateNotificationRecord(null, tv).getNotification(), 0);
   1232         verify(mRankingHelper, times(1)).getNotificationChannel(
   1233                 anyString(), anyInt(), eq("foo"), anyBoolean());
   1234     }
   1235 
   1236     @Test
   1237     public void testTvExtenderChannelOverride_notOnTv() throws Exception {
   1238         mService.setIsTelevision(false);
   1239         mService.setRankingHelper(mRankingHelper);
   1240         when(mRankingHelper.getNotificationChannel(
   1241                 anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
   1242                 mTestNotificationChannel);
   1243 
   1244         Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
   1245         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
   1246                 generateNotificationRecord(null, tv).getNotification(), 0);
   1247         verify(mRankingHelper, times(1)).getNotificationChannel(
   1248                 anyString(), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean());
   1249     }
   1250 
   1251     @Test
   1252     public void testUpdateAppNotifyCreatorBlock() throws Exception {
   1253         mService.setRankingHelper(mRankingHelper);
   1254 
   1255         mBinderService.setNotificationsEnabledForPackage(PKG, 0, false);
   1256         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
   1257         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
   1258 
   1259         assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
   1260                 captor.getValue().getAction());
   1261         assertEquals(PKG, captor.getValue().getPackage());
   1262         assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
   1263     }
   1264 
   1265     @Test
   1266     public void testUpdateAppNotifyCreatorUnblock() throws Exception {
   1267         mService.setRankingHelper(mRankingHelper);
   1268 
   1269         mBinderService.setNotificationsEnabledForPackage(PKG, 0, true);
   1270         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
   1271         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
   1272 
   1273         assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
   1274                 captor.getValue().getAction());
   1275         assertEquals(PKG, captor.getValue().getPackage());
   1276         assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
   1277     }
   1278 
   1279     @Test
   1280     public void testUpdateChannelNotifyCreatorBlock() throws Exception {
   1281         mService.setRankingHelper(mRankingHelper);
   1282         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
   1283                 eq(mTestNotificationChannel.getId()), anyBoolean()))
   1284                 .thenReturn(mTestNotificationChannel);
   1285 
   1286         NotificationChannel updatedChannel =
   1287                 new NotificationChannel(mTestNotificationChannel.getId(),
   1288                         mTestNotificationChannel.getName(), IMPORTANCE_NONE);
   1289 
   1290         mBinderService.updateNotificationChannelForPackage(PKG, 0, updatedChannel);
   1291         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
   1292         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
   1293 
   1294         assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED,
   1295                 captor.getValue().getAction());
   1296         assertEquals(PKG, captor.getValue().getPackage());
   1297         assertEquals(mTestNotificationChannel.getId(), captor.getValue().getStringExtra(
   1298                         NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
   1299         assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
   1300     }
   1301 
   1302     @Test
   1303     public void testUpdateChannelNotifyCreatorUnblock() throws Exception {
   1304         NotificationChannel existingChannel =
   1305                 new NotificationChannel(mTestNotificationChannel.getId(),
   1306                         mTestNotificationChannel.getName(), IMPORTANCE_NONE);
   1307         mService.setRankingHelper(mRankingHelper);
   1308         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
   1309                 eq(mTestNotificationChannel.getId()), anyBoolean()))
   1310                 .thenReturn(existingChannel);
   1311 
   1312         mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
   1313         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
   1314         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
   1315 
   1316         assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED,
   1317                 captor.getValue().getAction());
   1318         assertEquals(PKG, captor.getValue().getPackage());
   1319         assertEquals(mTestNotificationChannel.getId(), captor.getValue().getStringExtra(
   1320                 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
   1321         assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
   1322     }
   1323 
   1324     @Test
   1325     public void testUpdateChannelNoNotifyCreatorOtherChanges() throws Exception {
   1326         NotificationChannel existingChannel =
   1327                 new NotificationChannel(mTestNotificationChannel.getId(),
   1328                         mTestNotificationChannel.getName(), IMPORTANCE_MAX);
   1329         mService.setRankingHelper(mRankingHelper);
   1330         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
   1331                 eq(mTestNotificationChannel.getId()), anyBoolean()))
   1332                 .thenReturn(existingChannel);
   1333 
   1334         mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
   1335         verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
   1336     }
   1337 
   1338     @Test
   1339     public void testUpdateGroupNotifyCreatorBlock() throws Exception {
   1340         NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
   1341         mService.setRankingHelper(mRankingHelper);
   1342         when(mRankingHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
   1343                 .thenReturn(existing);
   1344 
   1345         NotificationChannelGroup updated = new NotificationChannelGroup("id", "name");
   1346         updated.setBlocked(true);
   1347 
   1348         mBinderService.updateNotificationChannelGroupForPackage(PKG, 0, updated);
   1349         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
   1350         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
   1351 
   1352         assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED,
   1353                 captor.getValue().getAction());
   1354         assertEquals(PKG, captor.getValue().getPackage());
   1355         assertEquals(existing.getId(), captor.getValue().getStringExtra(
   1356                 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
   1357         assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
   1358     }
   1359 
   1360     @Test
   1361     public void testUpdateGroupNotifyCreatorUnblock() throws Exception {
   1362         NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
   1363         existing.setBlocked(true);
   1364         mService.setRankingHelper(mRankingHelper);
   1365         when(mRankingHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
   1366                 .thenReturn(existing);
   1367 
   1368         mBinderService.updateNotificationChannelGroupForPackage(
   1369                 PKG, 0, new NotificationChannelGroup("id", "name"));
   1370         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
   1371         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
   1372 
   1373         assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED,
   1374                 captor.getValue().getAction());
   1375         assertEquals(PKG, captor.getValue().getPackage());
   1376         assertEquals(existing.getId(), captor.getValue().getStringExtra(
   1377                 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
   1378         assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
   1379     }
   1380 
   1381     @Test
   1382     public void testUpdateGroupNoNotifyCreatorOtherChanges() throws Exception {
   1383         NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
   1384         mService.setRankingHelper(mRankingHelper);
   1385         when(mRankingHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
   1386                 .thenReturn(existing);
   1387 
   1388         mBinderService.updateNotificationChannelGroupForPackage(
   1389                 PKG, 0, new NotificationChannelGroup("id", "new name"));
   1390         verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
   1391     }
   1392 
   1393     @Test
   1394     public void testCreateChannelNotifyListener() throws Exception {
   1395         List<String> associations = new ArrayList<>();
   1396         associations.add("a");
   1397         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1398         mService.setRankingHelper(mRankingHelper);
   1399         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
   1400                 eq(mTestNotificationChannel.getId()), anyBoolean()))
   1401                 .thenReturn(mTestNotificationChannel);
   1402         NotificationChannel channel2 = new NotificationChannel("a", "b", IMPORTANCE_LOW);
   1403         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
   1404                 eq(channel2.getId()), anyBoolean()))
   1405                 .thenReturn(channel2);
   1406 
   1407         reset(mListeners);
   1408         mBinderService.createNotificationChannels(PKG,
   1409                 new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
   1410         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
   1411                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
   1412                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
   1413         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
   1414                 eq(Process.myUserHandle()), eq(channel2),
   1415                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
   1416     }
   1417 
   1418     @Test
   1419     public void testCreateChannelGroupNotifyListener() throws Exception {
   1420         List<String> associations = new ArrayList<>();
   1421         associations.add("a");
   1422         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1423         mService.setRankingHelper(mRankingHelper);
   1424         NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
   1425         NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
   1426 
   1427         reset(mListeners);
   1428         mBinderService.createNotificationChannelGroups(PKG,
   1429                 new ParceledListSlice(Arrays.asList(group1, group2)));
   1430         verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
   1431                 eq(Process.myUserHandle()), eq(group1),
   1432                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
   1433         verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
   1434                 eq(Process.myUserHandle()), eq(group2),
   1435                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
   1436     }
   1437 
   1438     @Test
   1439     public void testUpdateChannelNotifyListener() throws Exception {
   1440         List<String> associations = new ArrayList<>();
   1441         associations.add("a");
   1442         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1443         mService.setRankingHelper(mRankingHelper);
   1444         mTestNotificationChannel.setLightColor(Color.CYAN);
   1445         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
   1446                 eq(mTestNotificationChannel.getId()), anyBoolean()))
   1447                 .thenReturn(mTestNotificationChannel);
   1448 
   1449         reset(mListeners);
   1450         mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
   1451         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
   1452                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
   1453                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
   1454     }
   1455 
   1456     @Test
   1457     public void testDeleteChannelNotifyListener() throws Exception {
   1458         List<String> associations = new ArrayList<>();
   1459         associations.add("a");
   1460         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1461         mService.setRankingHelper(mRankingHelper);
   1462         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
   1463                 eq(mTestNotificationChannel.getId()), anyBoolean()))
   1464                 .thenReturn(mTestNotificationChannel);
   1465         reset(mListeners);
   1466         mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
   1467         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
   1468                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
   1469                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
   1470     }
   1471 
   1472     @Test
   1473     public void testDeleteChannelGroupNotifyListener() throws Exception {
   1474         List<String> associations = new ArrayList<>();
   1475         associations.add("a");
   1476         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1477         NotificationChannelGroup ncg = new NotificationChannelGroup("a", "b/c");
   1478         mService.setRankingHelper(mRankingHelper);
   1479         when(mRankingHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt()))
   1480                 .thenReturn(ncg);
   1481         reset(mListeners);
   1482         mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId());
   1483         verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
   1484                 eq(Process.myUserHandle()), eq(ncg),
   1485                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
   1486     }
   1487 
   1488     @Test
   1489     public void testUpdateNotificationChannelFromPrivilegedListener_success() throws Exception {
   1490         mService.setRankingHelper(mRankingHelper);
   1491         List<String> associations = new ArrayList<>();
   1492         associations.add("a");
   1493         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1494         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
   1495                 eq(mTestNotificationChannel.getId()), anyBoolean()))
   1496                 .thenReturn(mTestNotificationChannel);
   1497 
   1498         mBinderService.updateNotificationChannelFromPrivilegedListener(
   1499                 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
   1500 
   1501         verify(mRankingHelper, times(1)).updateNotificationChannel(
   1502                 anyString(), anyInt(), any(), anyBoolean());
   1503 
   1504         verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
   1505                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
   1506                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
   1507     }
   1508 
   1509     @Test
   1510     public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
   1511         mService.setRankingHelper(mRankingHelper);
   1512         List<String> associations = new ArrayList<>();
   1513         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1514 
   1515         try {
   1516             mBinderService.updateNotificationChannelFromPrivilegedListener(
   1517                     null, PKG, Process.myUserHandle(), mTestNotificationChannel);
   1518             fail("listeners that don't have a companion device shouldn't be able to call this");
   1519         } catch (SecurityException e) {
   1520             // pass
   1521         }
   1522 
   1523         verify(mRankingHelper, never()).updateNotificationChannel(
   1524                 anyString(), anyInt(), any(), anyBoolean());
   1525 
   1526         verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
   1527                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
   1528                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
   1529     }
   1530 
   1531     @Test
   1532     public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
   1533         mService.setRankingHelper(mRankingHelper);
   1534         List<String> associations = new ArrayList<>();
   1535         associations.add("a");
   1536         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1537         mListener = mock(ManagedServices.ManagedServiceInfo.class);
   1538         mListener.component = new ComponentName(PKG, PKG);
   1539         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
   1540         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
   1541 
   1542         try {
   1543             mBinderService.updateNotificationChannelFromPrivilegedListener(
   1544                     null, PKG, UserHandle.ALL, mTestNotificationChannel);
   1545             fail("incorrectly allowed a change to a user listener cannot see");
   1546         } catch (SecurityException e) {
   1547             // pass
   1548         }
   1549 
   1550         verify(mRankingHelper, never()).updateNotificationChannel(
   1551                 anyString(), anyInt(), any(), anyBoolean());
   1552 
   1553         verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
   1554                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
   1555                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
   1556     }
   1557 
   1558     @Test
   1559     public void testGetNotificationChannelFromPrivilegedListener_success() throws Exception {
   1560         mService.setRankingHelper(mRankingHelper);
   1561         List<String> associations = new ArrayList<>();
   1562         associations.add("a");
   1563         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1564 
   1565         mBinderService.getNotificationChannelsFromPrivilegedListener(
   1566                 null, PKG, Process.myUserHandle());
   1567 
   1568         verify(mRankingHelper, times(1)).getNotificationChannels(
   1569                 anyString(), anyInt(), anyBoolean());
   1570     }
   1571 
   1572     @Test
   1573     public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
   1574         mService.setRankingHelper(mRankingHelper);
   1575         List<String> associations = new ArrayList<>();
   1576         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1577 
   1578         try {
   1579             mBinderService.getNotificationChannelsFromPrivilegedListener(
   1580                     null, PKG, Process.myUserHandle());
   1581             fail("listeners that don't have a companion device shouldn't be able to call this");
   1582         } catch (SecurityException e) {
   1583             // pass
   1584         }
   1585 
   1586         verify(mRankingHelper, never()).getNotificationChannels(
   1587                 anyString(), anyInt(), anyBoolean());
   1588     }
   1589 
   1590     @Test
   1591     public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
   1592         mService.setRankingHelper(mRankingHelper);
   1593         List<String> associations = new ArrayList<>();
   1594         associations.add("a");
   1595         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1596         mListener = mock(ManagedServices.ManagedServiceInfo.class);
   1597         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
   1598         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
   1599 
   1600         try {
   1601             mBinderService.getNotificationChannelsFromPrivilegedListener(
   1602                     null, PKG, Process.myUserHandle());
   1603             fail("listener getting channels from a user they cannot see");
   1604         } catch (SecurityException e) {
   1605             // pass
   1606         }
   1607 
   1608         verify(mRankingHelper, never()).getNotificationChannels(
   1609                 anyString(), anyInt(), anyBoolean());
   1610     }
   1611 
   1612     @Test
   1613     public void testGetNotificationChannelGroupsFromPrivilegedListener_success() throws Exception {
   1614         mService.setRankingHelper(mRankingHelper);
   1615         List<String> associations = new ArrayList<>();
   1616         associations.add("a");
   1617         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1618 
   1619         mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
   1620                 null, PKG, Process.myUserHandle());
   1621 
   1622         verify(mRankingHelper, times(1)).getNotificationChannelGroups(anyString(), anyInt());
   1623     }
   1624 
   1625     @Test
   1626     public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception {
   1627         mService.setRankingHelper(mRankingHelper);
   1628         List<String> associations = new ArrayList<>();
   1629         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1630 
   1631         try {
   1632             mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
   1633                     null, PKG, Process.myUserHandle());
   1634             fail("listeners that don't have a companion device shouldn't be able to call this");
   1635         } catch (SecurityException e) {
   1636             // pass
   1637         }
   1638 
   1639         verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
   1640     }
   1641 
   1642     @Test
   1643     public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
   1644         mService.setRankingHelper(mRankingHelper);
   1645         List<String> associations = new ArrayList<>();
   1646         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
   1647         mListener = mock(ManagedServices.ManagedServiceInfo.class);
   1648         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
   1649         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
   1650 
   1651         try {
   1652             mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
   1653                     null, PKG, Process.myUserHandle());
   1654             fail("listeners that don't have a companion device shouldn't be able to call this");
   1655         } catch (SecurityException e) {
   1656             // pass
   1657         }
   1658 
   1659         verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
   1660     }
   1661 
   1662     @Test
   1663     public void testHasCompanionDevice_failure() throws Exception {
   1664         when(mCompanionMgr.getAssociations(anyString(), anyInt())).thenThrow(
   1665                 new IllegalArgumentException());
   1666         mService.hasCompanionDevice(mListener);
   1667     }
   1668 
   1669     @Test
   1670     public void testHasCompanionDevice_noService() throws Exception {
   1671         mService = new TestableNotificationManagerService(mContext);
   1672 
   1673         assertFalse(mService.hasCompanionDevice(mListener));
   1674     }
   1675 
   1676     @Test
   1677     public void testSnoozeRunnable_snoozeNonGrouped() throws Exception {
   1678         final NotificationRecord nonGrouped = generateNotificationRecord(
   1679                 mTestNotificationChannel, 1, null, false);
   1680         final NotificationRecord grouped = generateNotificationRecord(
   1681                 mTestNotificationChannel, 2, "group", false);
   1682         mService.addNotification(grouped);
   1683         mService.addNotification(nonGrouped);
   1684 
   1685         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
   1686                 mService.new SnoozeNotificationRunnable(
   1687                         nonGrouped.getKey(), 100, null);
   1688         snoozeNotificationRunnable.run();
   1689 
   1690         // only snooze the one notification
   1691         verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
   1692         assertTrue(nonGrouped.getStats().hasSnoozed());
   1693     }
   1694 
   1695     @Test
   1696     public void testSnoozeRunnable_snoozeSummary_withChildren() throws Exception {
   1697         final NotificationRecord parent = generateNotificationRecord(
   1698                 mTestNotificationChannel, 1, "group", true);
   1699         final NotificationRecord child = generateNotificationRecord(
   1700                 mTestNotificationChannel, 2, "group", false);
   1701         final NotificationRecord child2 = generateNotificationRecord(
   1702                 mTestNotificationChannel, 3, "group", false);
   1703         mService.addNotification(parent);
   1704         mService.addNotification(child);
   1705         mService.addNotification(child2);
   1706 
   1707         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
   1708                 mService.new SnoozeNotificationRunnable(
   1709                         parent.getKey(), 100, null);
   1710         snoozeNotificationRunnable.run();
   1711 
   1712         // snooze parent and children
   1713         verify(mSnoozeHelper, times(3)).snooze(any(NotificationRecord.class), anyLong());
   1714     }
   1715 
   1716     @Test
   1717     public void testSnoozeRunnable_snoozeGroupChild_fellowChildren() throws Exception {
   1718         final NotificationRecord parent = generateNotificationRecord(
   1719                 mTestNotificationChannel, 1, "group", true);
   1720         final NotificationRecord child = generateNotificationRecord(
   1721                 mTestNotificationChannel, 2, "group", false);
   1722         final NotificationRecord child2 = generateNotificationRecord(
   1723                 mTestNotificationChannel, 3, "group", false);
   1724         mService.addNotification(parent);
   1725         mService.addNotification(child);
   1726         mService.addNotification(child2);
   1727 
   1728         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
   1729                 mService.new SnoozeNotificationRunnable(
   1730                         child2.getKey(), 100, null);
   1731         snoozeNotificationRunnable.run();
   1732 
   1733         // only snooze the one child
   1734         verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
   1735     }
   1736 
   1737     @Test
   1738     public void testSnoozeRunnable_snoozeGroupChild_onlyChildOfSummary() throws Exception {
   1739         final NotificationRecord parent = generateNotificationRecord(
   1740                 mTestNotificationChannel, 1, "group", true);
   1741         assertTrue(parent.sbn.getNotification().isGroupSummary());
   1742         final NotificationRecord child = generateNotificationRecord(
   1743                 mTestNotificationChannel, 2, "group", false);
   1744         mService.addNotification(parent);
   1745         mService.addNotification(child);
   1746 
   1747         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
   1748                 mService.new SnoozeNotificationRunnable(
   1749                         child.getKey(), 100, null);
   1750         snoozeNotificationRunnable.run();
   1751 
   1752         // snooze child and summary
   1753         verify(mSnoozeHelper, times(2)).snooze(any(NotificationRecord.class), anyLong());
   1754     }
   1755 
   1756     @Test
   1757     public void testSnoozeRunnable_snoozeGroupChild_noOthersInGroup() throws Exception {
   1758         final NotificationRecord child = generateNotificationRecord(
   1759                 mTestNotificationChannel, 2, "group", false);
   1760         mService.addNotification(child);
   1761 
   1762         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
   1763                 mService.new SnoozeNotificationRunnable(
   1764                         child.getKey(), 100, null);
   1765         snoozeNotificationRunnable.run();
   1766 
   1767         // snooze child only
   1768         verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
   1769     }
   1770 
   1771     @Test
   1772     public void testPostGroupChild_unsnoozeParent() throws Exception {
   1773         final NotificationRecord child = generateNotificationRecord(
   1774                 mTestNotificationChannel, 2, "group", false);
   1775 
   1776         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
   1777                 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
   1778         waitForIdle();
   1779 
   1780         verify(mSnoozeHelper, times(1)).repostGroupSummary(
   1781                 anyString(), anyInt(), eq(child.getGroupKey()));
   1782     }
   1783 
   1784     @Test
   1785     public void testPostNonGroup_noUnsnoozing() throws Exception {
   1786         final NotificationRecord record = generateNotificationRecord(
   1787                 mTestNotificationChannel, 2, null, false);
   1788 
   1789         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
   1790                 record.sbn.getId(), record.sbn.getNotification(), record.sbn.getUserId());
   1791         waitForIdle();
   1792 
   1793         verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
   1794     }
   1795 
   1796     @Test
   1797     public void testPostGroupSummary_noUnsnoozing() throws Exception {
   1798         final NotificationRecord parent = generateNotificationRecord(
   1799                 mTestNotificationChannel, 2, "group", true);
   1800 
   1801         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
   1802                 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
   1803         waitForIdle();
   1804 
   1805         verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
   1806     }
   1807 
   1808     @Test
   1809     public void testSetListenerAccessForUser() throws Exception {
   1810         UserHandle user = UserHandle.of(10);
   1811         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1812         try {
   1813             mBinderService.setNotificationListenerAccessGrantedForUser(
   1814                     c, user.getIdentifier(), true);
   1815         } catch (SecurityException e) {
   1816             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1817                 throw e;
   1818             }
   1819         }
   1820 
   1821         verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
   1822         verify(mListeners, times(1)).setPackageOrComponentEnabled(
   1823                 c.flattenToString(), user.getIdentifier(), true, true);
   1824         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1825                 c.flattenToString(), user.getIdentifier(), false, true);
   1826         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1827                 any(), anyInt(), anyBoolean(), anyBoolean());
   1828     }
   1829 
   1830     @Test
   1831     public void testSetAssistantAccessForUser() throws Exception {
   1832         UserHandle user = UserHandle.of(10);
   1833         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1834         try {
   1835             mBinderService.setNotificationAssistantAccessGrantedForUser(
   1836                     c, user.getIdentifier(), true);
   1837         } catch (SecurityException e) {
   1838             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1839                 throw e;
   1840             }
   1841         }
   1842 
   1843         verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
   1844         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
   1845                 c.flattenToString(), user.getIdentifier(), true, true);
   1846         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1847                 c.flattenToString(), user.getIdentifier(), false, true);
   1848         verify(mListeners, never()).setPackageOrComponentEnabled(
   1849                 any(), anyInt(), anyBoolean(), anyBoolean());
   1850     }
   1851 
   1852     @Test
   1853     public void testSetDndAccessForUser() throws Exception {
   1854         UserHandle user = UserHandle.of(10);
   1855         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1856         try {
   1857             mBinderService.setNotificationPolicyAccessGrantedForUser(
   1858                     c.getPackageName(), user.getIdentifier(), true);
   1859         } catch (SecurityException e) {
   1860             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1861                 throw e;
   1862             }
   1863         }
   1864 
   1865         verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
   1866         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1867                 c.getPackageName(), user.getIdentifier(), true, true);
   1868         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1869                 any(), anyInt(), anyBoolean(), anyBoolean());
   1870         verify(mListeners, never()).setPackageOrComponentEnabled(
   1871                 any(), anyInt(), anyBoolean(), anyBoolean());
   1872     }
   1873 
   1874     @Test
   1875     public void testSetListenerAccess() throws Exception {
   1876         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1877         try {
   1878             mBinderService.setNotificationListenerAccessGranted(c, true);
   1879         } catch (SecurityException e) {
   1880             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1881                 throw e;
   1882             }
   1883         }
   1884 
   1885         verify(mListeners, times(1)).setPackageOrComponentEnabled(
   1886                 c.flattenToString(), 0, true, true);
   1887         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1888                 c.flattenToString(), 0, false, true);
   1889         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1890                 any(), anyInt(), anyBoolean(), anyBoolean());
   1891     }
   1892 
   1893     @Test
   1894     public void testSetAssistantAccess() throws Exception {
   1895         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1896         try {
   1897             mBinderService.setNotificationAssistantAccessGranted(c, true);
   1898         } catch (SecurityException e) {
   1899             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1900                 throw e;
   1901             }
   1902         }
   1903 
   1904         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
   1905                 c.flattenToString(), 0, true, true);
   1906         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1907                 c.flattenToString(), 0, false, true);
   1908         verify(mListeners, never()).setPackageOrComponentEnabled(
   1909                 any(), anyInt(), anyBoolean(), anyBoolean());
   1910     }
   1911 
   1912     @Test
   1913     public void testSetDndAccess() throws Exception {
   1914         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1915         try {
   1916             mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
   1917         } catch (SecurityException e) {
   1918             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1919                 throw e;
   1920             }
   1921         }
   1922 
   1923         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1924                 c.getPackageName(), 0, true, true);
   1925         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1926                 any(), anyInt(), anyBoolean(), anyBoolean());
   1927         verify(mListeners, never()).setPackageOrComponentEnabled(
   1928                 any(), anyInt(), anyBoolean(), anyBoolean());
   1929     }
   1930 
   1931     @Test
   1932     public void testSetListenerAccess_doesNothingOnLowRam() throws Exception {
   1933         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   1934         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1935         mBinderService.setNotificationListenerAccessGranted(c, true);
   1936 
   1937         verify(mListeners, never()).setPackageOrComponentEnabled(
   1938                 anyString(), anyInt(), anyBoolean(), anyBoolean());
   1939         verify(mConditionProviders, never()).setPackageOrComponentEnabled(
   1940                 anyString(), anyInt(), anyBoolean(), anyBoolean());
   1941         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1942                 any(), anyInt(), anyBoolean(), anyBoolean());
   1943     }
   1944 
   1945     @Test
   1946     public void testSetAssistantAccess_doesNothingOnLowRam() throws Exception {
   1947         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   1948         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1949         mBinderService.setNotificationAssistantAccessGranted(c, true);
   1950 
   1951         verify(mListeners, never()).setPackageOrComponentEnabled(
   1952                 anyString(), anyInt(), anyBoolean(), anyBoolean());
   1953         verify(mConditionProviders, never()).setPackageOrComponentEnabled(
   1954                 anyString(), anyInt(), anyBoolean(), anyBoolean());
   1955         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1956                 any(), anyInt(), anyBoolean(), anyBoolean());
   1957     }
   1958 
   1959     @Test
   1960     public void testSetDndAccess_doesNothingOnLowRam() throws Exception {
   1961         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   1962         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1963         mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
   1964 
   1965         verify(mListeners, never()).setPackageOrComponentEnabled(
   1966                 anyString(), anyInt(), anyBoolean(), anyBoolean());
   1967         verify(mConditionProviders, never()).setPackageOrComponentEnabled(
   1968                 anyString(), anyInt(), anyBoolean(), anyBoolean());
   1969         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1970                 any(), anyInt(), anyBoolean(), anyBoolean());
   1971     }
   1972 
   1973     @Test
   1974     public void testSetListenerAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
   1975         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
   1976         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   1977         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1978         try {
   1979             mBinderService.setNotificationListenerAccessGranted(c, true);
   1980         } catch (SecurityException e) {
   1981             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   1982                 throw e;
   1983             }
   1984         }
   1985 
   1986         verify(mListeners, times(1)).setPackageOrComponentEnabled(
   1987                 c.flattenToString(), 0, true, true);
   1988         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   1989                 c.flattenToString(), 0, false, true);
   1990         verify(mAssistants, never()).setPackageOrComponentEnabled(
   1991                 any(), anyInt(), anyBoolean(), anyBoolean());
   1992     }
   1993 
   1994     @Test
   1995     public void testSetAssistantAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
   1996         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
   1997         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   1998         ComponentName c = ComponentName.unflattenFromString("package/Component");
   1999         try {
   2000             mBinderService.setNotificationAssistantAccessGranted(c, true);
   2001         } catch (SecurityException e) {
   2002             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   2003                 throw e;
   2004             }
   2005         }
   2006 
   2007         verify(mListeners, never()).setPackageOrComponentEnabled(
   2008                 anyString(), anyInt(), anyBoolean(), anyBoolean());
   2009         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   2010                 c.flattenToString(), 0, false, true);
   2011         verify(mAssistants, times(1)).setPackageOrComponentEnabled(
   2012                 c.flattenToString(), 0, true, true);
   2013     }
   2014 
   2015     @Test
   2016     public void testSetDndAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
   2017         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
   2018         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   2019         ComponentName c = ComponentName.unflattenFromString("package/Component");
   2020         try {
   2021             mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
   2022         } catch (SecurityException e) {
   2023             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
   2024                 throw e;
   2025             }
   2026         }
   2027 
   2028         verify(mListeners, never()).setPackageOrComponentEnabled(
   2029                 anyString(), anyInt(), anyBoolean(), anyBoolean());
   2030         verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
   2031                 c.getPackageName(), 0, true, true);
   2032         verify(mAssistants, never()).setPackageOrComponentEnabled(
   2033                 any(), anyInt(), anyBoolean(), anyBoolean());
   2034     }
   2035 
   2036     @Test
   2037     public void testOnlyAutogroupIfGroupChanged_noPriorNoti_autogroups() throws Exception {
   2038         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
   2039         mService.addEnqueuedNotification(r);
   2040         NotificationManagerService.PostNotificationRunnable runnable =
   2041                 mService.new PostNotificationRunnable(r.getKey());
   2042         runnable.run();
   2043         waitForIdle();
   2044 
   2045         verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
   2046     }
   2047 
   2048     @Test
   2049     public void testOnlyAutogroupIfGroupChanged_groupChanged_autogroups()
   2050             throws Exception {
   2051         NotificationRecord r =
   2052                 generateNotificationRecord(mTestNotificationChannel, 0, "group", false);
   2053         mService.addNotification(r);
   2054 
   2055         r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
   2056         mService.addEnqueuedNotification(r);
   2057         NotificationManagerService.PostNotificationRunnable runnable =
   2058                 mService.new PostNotificationRunnable(r.getKey());
   2059         runnable.run();
   2060         waitForIdle();
   2061 
   2062         verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
   2063     }
   2064 
   2065     @Test
   2066     public void testOnlyAutogroupIfGroupChanged_noGroupChanged_autogroups()
   2067             throws Exception {
   2068         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group",
   2069                 false);
   2070         mService.addNotification(r);
   2071         mService.addEnqueuedNotification(r);
   2072 
   2073         NotificationManagerService.PostNotificationRunnable runnable =
   2074                 mService.new PostNotificationRunnable(r.getKey());
   2075         runnable.run();
   2076         waitForIdle();
   2077 
   2078         verify(mGroupHelper, never()).onNotificationPosted(any(), anyBoolean());
   2079     }
   2080 
   2081     @Test
   2082     public void testNoFakeColorizedPermission() throws Exception {
   2083         when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED);
   2084         Notification.Builder nb = new Notification.Builder(mContext,
   2085                 mTestNotificationChannel.getId())
   2086                 .setContentTitle("foo")
   2087                 .setColorized(true)
   2088                 .setFlag(Notification.FLAG_CAN_COLORIZE, true)
   2089                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
   2090         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
   2091                 nb.build(), new UserHandle(mUid), null, 0);
   2092         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
   2093 
   2094         mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
   2095                 nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
   2096         waitForIdle();
   2097 
   2098         NotificationRecord posted = mService.findNotificationLocked(
   2099                 PKG, null, nr.sbn.getId(), nr.sbn.getUserId());
   2100 
   2101         assertFalse(posted.getNotification().isColorized());
   2102     }
   2103 
   2104     @Test
   2105     public void testGetNotificationCountLocked() throws Exception {
   2106         for (int i = 0; i < 20; i++) {
   2107             NotificationRecord r =
   2108                     generateNotificationRecord(mTestNotificationChannel, i, null, false);
   2109             mService.addEnqueuedNotification(r);
   2110         }
   2111         for (int i = 0; i < 20; i++) {
   2112             NotificationRecord r =
   2113                     generateNotificationRecord(mTestNotificationChannel, i, null, false);
   2114             mService.addNotification(r);
   2115         }
   2116 
   2117         // another package
   2118         Notification n =
   2119                 new Notification.Builder(mContext, mTestNotificationChannel.getId())
   2120                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
   2121                 .build();
   2122 
   2123         StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "tag", mUid, 0,
   2124                 n, new UserHandle(mUid), null, 0);
   2125         NotificationRecord otherPackage =
   2126                 new NotificationRecord(mContext, sbn, mTestNotificationChannel);
   2127         mService.addEnqueuedNotification(otherPackage);
   2128         mService.addNotification(otherPackage);
   2129 
   2130         // Same notifications are enqueued as posted, everything counts b/c id and tag don't match
   2131         int userId = new UserHandle(mUid).getIdentifier();
   2132         assertEquals(40,
   2133                 mService.getNotificationCountLocked(PKG, userId, 0, null));
   2134         assertEquals(40,
   2135                 mService.getNotificationCountLocked(PKG, userId, 0, "tag2"));
   2136         assertEquals(2,
   2137                 mService.getNotificationCountLocked("a", userId, 0, "banana"));
   2138 
   2139         // exclude a known notification - it's excluded from only the posted list, not enqueued
   2140         assertEquals(39,
   2141                 mService.getNotificationCountLocked(PKG, userId, 0, "tag"));
   2142     }
   2143 
   2144     @Test
   2145     public void testAddAutogroup_requestsSort() throws Exception {
   2146         RankingHandler rh = mock(RankingHandler.class);
   2147         mService.setRankingHandler(rh);
   2148 
   2149         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2150         mService.addNotification(r);
   2151         mService.addAutogroupKeyLocked(r.getKey());
   2152 
   2153         verify(rh, times(1)).requestSort();
   2154     }
   2155 
   2156     @Test
   2157     public void testRemoveAutogroup_requestsSort() throws Exception {
   2158         RankingHandler rh = mock(RankingHandler.class);
   2159         mService.setRankingHandler(rh);
   2160 
   2161         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2162         r.setOverrideGroupKey("TEST");
   2163         mService.addNotification(r);
   2164         mService.removeAutogroupKeyLocked(r.getKey());
   2165 
   2166         verify(rh, times(1)).requestSort();
   2167     }
   2168 
   2169     @Test
   2170     public void testReaddAutogroup_noSort() throws Exception {
   2171         RankingHandler rh = mock(RankingHandler.class);
   2172         mService.setRankingHandler(rh);
   2173 
   2174         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2175         r.setOverrideGroupKey("TEST");
   2176         mService.addNotification(r);
   2177         mService.addAutogroupKeyLocked(r.getKey());
   2178 
   2179         verify(rh, never()).requestSort();
   2180     }
   2181 
   2182     @Test
   2183     public void testHandleRankingSort_sendsUpdateOnSignalExtractorChange() throws Exception {
   2184         mService.setRankingHelper(mRankingHelper);
   2185         NotificationManagerService.WorkerHandler handler = mock(
   2186                 NotificationManagerService.WorkerHandler.class);
   2187         mService.setHandler(handler);
   2188 
   2189         Map<String, Answer> answers = getSignalExtractorSideEffects();
   2190         for (String message : answers.keySet()) {
   2191             mService.clearNotifications();
   2192             final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2193             mService.addNotification(r);
   2194 
   2195             doAnswer(answers.get(message)).when(mRankingHelper).extractSignals(r);
   2196 
   2197             mService.handleRankingSort();
   2198         }
   2199         verify(handler, times(answers.size())).scheduleSendRankingUpdate();
   2200     }
   2201 
   2202     @Test
   2203     public void testHandleRankingSort_noUpdateWhenNoSignalChange() throws Exception {
   2204         mService.setRankingHelper(mRankingHelper);
   2205         NotificationManagerService.WorkerHandler handler = mock(
   2206                 NotificationManagerService.WorkerHandler.class);
   2207         mService.setHandler(handler);
   2208 
   2209         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2210         mService.addNotification(r);
   2211 
   2212         mService.handleRankingSort();
   2213         verify(handler, never()).scheduleSendRankingUpdate();
   2214     }
   2215 
   2216     @Test
   2217     public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception {
   2218         final String upgradeXml = "<notification-policy version=\"1\">"
   2219                 + "<ranking></ranking>"
   2220                 + "<enabled_listeners>"
   2221                 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
   2222                 + "</enabled_listeners>"
   2223                 + "<enabled_assistants>"
   2224                 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
   2225                 + "</enabled_assistants>"
   2226                 + "<dnd_apps>"
   2227                 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
   2228                 + "</dnd_apps>"
   2229                 + "</notification-policy>";
   2230         mService.readPolicyXml(
   2231                 new BufferedInputStream(new ByteArrayInputStream(upgradeXml.getBytes())), false);
   2232         verify(mListeners, times(1)).readXml(any(), any());
   2233         verify(mConditionProviders, times(1)).readXml(any(), any());
   2234         verify(mAssistants, times(1)).readXml(any(), any());
   2235 
   2236         // numbers are inflated for setup
   2237         verify(mListeners, times(1)).migrateToXml();
   2238         verify(mConditionProviders, times(1)).migrateToXml();
   2239         verify(mAssistants, times(1)).migrateToXml();
   2240         verify(mAssistants, times(2)).ensureAssistant();
   2241     }
   2242 
   2243     @Test
   2244     public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception {
   2245         final String preupgradeXml = "<notification-policy version=\"1\">"
   2246                 + "<ranking></ranking>"
   2247                 + "</notification-policy>";
   2248         mService.readPolicyXml(
   2249                 new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
   2250         verify(mListeners, never()).readXml(any(), any());
   2251         verify(mConditionProviders, never()).readXml(any(), any());
   2252         verify(mAssistants, never()).readXml(any(), any());
   2253 
   2254         // numbers are inflated for setup
   2255         verify(mListeners, times(2)).migrateToXml();
   2256         verify(mConditionProviders, times(2)).migrateToXml();
   2257         verify(mAssistants, times(2)).migrateToXml();
   2258         verify(mAssistants, times(2)).ensureAssistant();
   2259     }
   2260 
   2261 
   2262     @Test
   2263     public void testLocaleChangedCallsUpdateDefaultZenModeRules() throws Exception {
   2264         ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
   2265         mService.mZenModeHelper = mZenModeHelper;
   2266         mService.mLocaleChangeReceiver.onReceive(mContext,
   2267                 new Intent(Intent.ACTION_LOCALE_CHANGED));
   2268 
   2269         verify(mZenModeHelper, times(1)).updateDefaultZenRules();
   2270     }
   2271 
   2272     @Test
   2273     public void testBumpFGImportance_noChannelChangePreOApp() throws Exception {
   2274         String preOPkg = PKG_N_MR1;
   2275         int preOUid = 145;
   2276         final ApplicationInfo legacy = new ApplicationInfo();
   2277         legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
   2278         when(mPackageManagerClient.getApplicationInfoAsUser(eq(preOPkg), anyInt(), anyInt()))
   2279                 .thenReturn(legacy);
   2280         when(mPackageManagerClient.getPackageUidAsUser(eq(preOPkg), anyInt())).thenReturn(preOUid);
   2281         getContext().setMockPackageManager(mPackageManagerClient);
   2282 
   2283         Notification.Builder nb = new Notification.Builder(mContext,
   2284                 NotificationChannel.DEFAULT_CHANNEL_ID)
   2285                 .setContentTitle("foo")
   2286                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
   2287                 .setFlag(FLAG_FOREGROUND_SERVICE, true)
   2288                 .setPriority(Notification.PRIORITY_MIN);
   2289 
   2290         StatusBarNotification sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid,
   2291                 0, nb.build(), new UserHandle(preOUid), null, 0);
   2292 
   2293         mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag",
   2294                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
   2295         waitForIdle();
   2296         assertEquals(IMPORTANCE_LOW,
   2297                 mService.getNotificationRecord(sbn.getKey()).getImportance());
   2298 
   2299         nb = new Notification.Builder(mContext)
   2300                 .setContentTitle("foo")
   2301                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
   2302                 .setFlag(FLAG_FOREGROUND_SERVICE, true)
   2303                 .setPriority(Notification.PRIORITY_MIN);
   2304 
   2305         sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid,
   2306                 0, nb.build(), new UserHandle(preOUid), null, 0);
   2307 
   2308         mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag",
   2309                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
   2310         waitForIdle();
   2311         assertEquals(IMPORTANCE_LOW,
   2312                 mService.getNotificationRecord(sbn.getKey()).getImportance());
   2313 
   2314         NotificationChannel defaultChannel = mBinderService.getNotificationChannel(
   2315                 preOPkg, NotificationChannel.DEFAULT_CHANNEL_ID);
   2316         assertEquals(IMPORTANCE_UNSPECIFIED, defaultChannel.getImportance());
   2317     }
   2318 
   2319     @Test
   2320     public void testStats_updatedOnDirectReply() throws Exception {
   2321         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2322         mService.addNotification(r);
   2323 
   2324         mService.mNotificationDelegate.onNotificationDirectReplied(r.getKey());
   2325         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasDirectReplied());
   2326     }
   2327 
   2328     @Test
   2329     public void testStats_updatedOnUserExpansion() throws Exception {
   2330         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2331         mService.addNotification(r);
   2332 
   2333         mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), true, true);
   2334         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
   2335         mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), true, false);
   2336         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
   2337     }
   2338 
   2339     @Test
   2340     public void testStats_notUpdatedOnAutoExpansion() throws Exception {
   2341         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2342         mService.addNotification(r);
   2343 
   2344         mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, true);
   2345         assertFalse(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
   2346         mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, false);
   2347         assertFalse(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
   2348     }
   2349 
   2350     @Test
   2351     public void testStats_updatedOnViewSettings() throws Exception {
   2352         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2353         mService.addNotification(r);
   2354 
   2355         mService.mNotificationDelegate.onNotificationSettingsViewed(r.getKey());
   2356         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasViewedSettings());
   2357     }
   2358 
   2359     @Test
   2360     public void testStats_updatedOnVisibilityChanged() throws Exception {
   2361         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2362         mService.addNotification(r);
   2363 
   2364         final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 1, 2, true);
   2365         mService.mNotificationDelegate.onNotificationVisibilityChanged(
   2366                 new NotificationVisibility[] {nv}, new NotificationVisibility[]{});
   2367         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasSeen());
   2368         mService.mNotificationDelegate.onNotificationVisibilityChanged(
   2369                 new NotificationVisibility[] {}, new NotificationVisibility[]{nv});
   2370         assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasSeen());
   2371     }
   2372 
   2373     @Test
   2374     public void testStats_dismissalSurface() throws Exception {
   2375         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2376         mService.addNotification(r);
   2377 
   2378         final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
   2379         mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.sbn.getTag(),
   2380                 r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD, nv);
   2381         waitForIdle();
   2382 
   2383         assertEquals(NotificationStats.DISMISSAL_AOD, r.getStats().getDismissalSurface());
   2384     }
   2385 
   2386     @Test
   2387     public void testUserSentimentChangeTriggersUpdate() throws Exception {
   2388         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
   2389         mService.addNotification(r);
   2390         NotificationManagerService.WorkerHandler handler = mock(
   2391                 NotificationManagerService.WorkerHandler.class);
   2392         mService.setHandler(handler);
   2393 
   2394         Bundle signals = new Bundle();
   2395         signals.putInt(Adjustment.KEY_USER_SENTIMENT,
   2396                 NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
   2397         Adjustment adjustment = new Adjustment(
   2398                 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
   2399         mBinderService.applyAdjustmentFromAssistant(null, adjustment);
   2400 
   2401         waitForIdle();
   2402 
   2403         verify(handler, timeout(300).times(1)).scheduleSendRankingUpdate();
   2404     }
   2405 
   2406     @Test
   2407     public void testRecents() throws Exception {
   2408         Set<NotifyingApp> expected = new HashSet<>();
   2409 
   2410         final NotificationRecord oldest = new NotificationRecord(mContext,
   2411                 generateSbn("p", 1000, 9, 0), mTestNotificationChannel);
   2412         mService.logRecentLocked(oldest);
   2413         for (int i = 1; i <= 5; i++) {
   2414             NotificationRecord r = new NotificationRecord(mContext,
   2415                     generateSbn("p" + i, i, i*100, 0), mTestNotificationChannel);
   2416             expected.add(new NotifyingApp()
   2417                     .setPackage(r.sbn.getPackageName())
   2418                     .setUid(r.sbn.getUid())
   2419                     .setLastNotified(r.sbn.getPostTime()));
   2420             mService.logRecentLocked(r);
   2421         }
   2422 
   2423         List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
   2424         assertTrue(apps.size() == 5);
   2425         for (NotifyingApp actual : apps) {
   2426             assertTrue("got unexpected result: " + actual, expected.contains(actual));
   2427         }
   2428     }
   2429 
   2430     @Test
   2431     public void testRecentsNoDuplicatePackages() throws Exception {
   2432         final NotificationRecord p1 = new NotificationRecord(mContext, generateSbn("p", 1, 1000, 0),
   2433                 mTestNotificationChannel);
   2434         final NotificationRecord p2 = new NotificationRecord(mContext, generateSbn("p", 1, 2000, 0),
   2435                 mTestNotificationChannel);
   2436 
   2437         mService.logRecentLocked(p1);
   2438         mService.logRecentLocked(p2);
   2439 
   2440         List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
   2441         assertTrue(apps.size() == 1);
   2442         NotifyingApp expected = new NotifyingApp().setPackage("p").setUid(1).setLastNotified(2000);
   2443         assertEquals(expected, apps.get(0));
   2444     }
   2445 
   2446     @Test
   2447     public void testRecentsWithDuplicatePackage() throws Exception {
   2448         Set<NotifyingApp> expected = new HashSet<>();
   2449 
   2450         final NotificationRecord oldest = new NotificationRecord(mContext,
   2451                 generateSbn("p", 1000, 9, 0), mTestNotificationChannel);
   2452         mService.logRecentLocked(oldest);
   2453         for (int i = 1; i <= 5; i++) {
   2454             NotificationRecord r = new NotificationRecord(mContext,
   2455                     generateSbn("p" + i, i, i*100, 0), mTestNotificationChannel);
   2456             expected.add(new NotifyingApp()
   2457                     .setPackage(r.sbn.getPackageName())
   2458                     .setUid(r.sbn.getUid())
   2459                     .setLastNotified(r.sbn.getPostTime()));
   2460             mService.logRecentLocked(r);
   2461         }
   2462         NotificationRecord r = new NotificationRecord(mContext,
   2463                 generateSbn("p" + 3, 3, 300000, 0), mTestNotificationChannel);
   2464         expected.remove(new NotifyingApp()
   2465                 .setPackage(r.sbn.getPackageName())
   2466                 .setUid(3)
   2467                 .setLastNotified(300));
   2468         NotifyingApp newest = new NotifyingApp()
   2469                 .setPackage(r.sbn.getPackageName())
   2470                 .setUid(r.sbn.getUid())
   2471                 .setLastNotified(r.sbn.getPostTime());
   2472         expected.add(newest);
   2473         mService.logRecentLocked(r);
   2474 
   2475         List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
   2476         assertTrue(apps.size() == 5);
   2477         for (NotifyingApp actual : apps) {
   2478             assertTrue("got unexpected result: " + actual, expected.contains(actual));
   2479         }
   2480         assertEquals(newest, apps.get(0));
   2481     }
   2482 
   2483     @Test
   2484     public void testRecentsMultiuser() throws Exception {
   2485         final NotificationRecord user1 = new NotificationRecord(mContext,
   2486                 generateSbn("p", 1000, 9, 1), mTestNotificationChannel);
   2487         mService.logRecentLocked(user1);
   2488 
   2489         final NotificationRecord user2 = new NotificationRecord(mContext,
   2490                 generateSbn("p2", 100000, 9999, 2), mTestNotificationChannel);
   2491         mService.logRecentLocked(user2);
   2492 
   2493         assertEquals(0, mBinderService.getRecentNotifyingAppsForUser(0).getList().size());
   2494         assertEquals(1, mBinderService.getRecentNotifyingAppsForUser(1).getList().size());
   2495         assertEquals(1, mBinderService.getRecentNotifyingAppsForUser(2).getList().size());
   2496 
   2497         assertTrue(mBinderService.getRecentNotifyingAppsForUser(2).getList().contains(
   2498                 new NotifyingApp()
   2499                         .setPackage(user2.sbn.getPackageName())
   2500                         .setUid(user2.sbn.getUid())
   2501                         .setLastNotified(user2.sbn.getPostTime())));
   2502     }
   2503 
   2504     @Test
   2505     public void testRestore() throws Exception {
   2506         int systemChecks = mService.countSystemChecks;
   2507         mBinderService.applyRestore(null, UserHandle.USER_SYSTEM);
   2508         assertEquals(1, mService.countSystemChecks - systemChecks);
   2509     }
   2510 
   2511     @Test
   2512     public void testBackup() throws Exception {
   2513         int systemChecks = mService.countSystemChecks;
   2514         mBinderService.getBackupPayload(1);
   2515         assertEquals(1, mService.countSystemChecks - systemChecks);
   2516     }
   2517 
   2518     @Test
   2519     public void updateUriPermissions_update() throws Exception {
   2520         NotificationChannel c = new NotificationChannel(
   2521                 TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
   2522         c.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
   2523         Message message1 = new Message("", 0, "");
   2524         message1.setData("",
   2525                 ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1));
   2526         Message message2 = new Message("", 1, "");
   2527         message2.setData("",
   2528                 ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 2));
   2529 
   2530         Notification.Builder nbA = new Notification.Builder(mContext, c.getId())
   2531                 .setContentTitle("foo")
   2532                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
   2533                 .setStyle(new Notification.MessagingStyle("")
   2534                         .addMessage(message1)
   2535                         .addMessage(message2));
   2536         NotificationRecord recordA = new NotificationRecord(mContext, new StatusBarNotification(
   2537                 PKG, PKG, 0, "tag", mUid, 0, nbA.build(), new UserHandle(mUid), null, 0), c);
   2538 
   2539         // First post means we grant access to both
   2540         reset(mAm);
   2541         when(mAm.newUriPermissionOwner(any())).thenReturn(new Binder());
   2542         mService.updateUriPermissions(recordA, null, mContext.getPackageName(),
   2543                 UserHandle.USER_SYSTEM);
   2544         verify(mAm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
   2545                 eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
   2546         verify(mAm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
   2547                 eq(message2.getDataUri()), anyInt(), anyInt(), anyInt());
   2548 
   2549         Notification.Builder nbB = new Notification.Builder(mContext, c.getId())
   2550                 .setContentTitle("foo")
   2551                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
   2552                 .setStyle(new Notification.MessagingStyle("").addMessage(message2));
   2553         NotificationRecord recordB = new NotificationRecord(mContext, new StatusBarNotification(PKG,
   2554                 PKG, 0, "tag", mUid, 0, nbB.build(), new UserHandle(mUid), null, 0), c);
   2555 
   2556         // Update means we drop access to first
   2557         reset(mAm);
   2558         mService.updateUriPermissions(recordB, recordA, mContext.getPackageName(),
   2559                 UserHandle.USER_SYSTEM);
   2560         verify(mAm, times(1)).revokeUriPermissionFromOwner(any(), eq(message1.getDataUri()),
   2561                 anyInt(), anyInt());
   2562 
   2563         // Update back means we grant access to first again
   2564         reset(mAm);
   2565         mService.updateUriPermissions(recordA, recordB, mContext.getPackageName(),
   2566                 UserHandle.USER_SYSTEM);
   2567         verify(mAm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
   2568                 eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
   2569 
   2570         // And update to empty means we drop everything
   2571         reset(mAm);
   2572         mService.updateUriPermissions(null, recordB, mContext.getPackageName(),
   2573                 UserHandle.USER_SYSTEM);
   2574         verify(mAm, times(1)).revokeUriPermissionFromOwner(any(), eq(null),
   2575                 anyInt(), anyInt());
   2576     }
   2577 
   2578     @Test
   2579     public void testSetNotificationPolicy_preP_setOldFields() {
   2580         ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
   2581         mService.mZenModeHelper = mZenModeHelper;
   2582         NotificationManager.Policy userPolicy =
   2583                 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
   2584         when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
   2585 
   2586         NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
   2587                 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF);
   2588 
   2589         int expected = SUPPRESSED_EFFECT_BADGE
   2590                 | SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF
   2591                 | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_LIGHTS
   2592                 | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
   2593         int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
   2594 
   2595         assertEquals(expected, actual);
   2596     }
   2597 
   2598     @Test
   2599     public void testSetNotificationPolicy_preP_setNewFields() {
   2600         ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
   2601         mService.mZenModeHelper = mZenModeHelper;
   2602         NotificationManager.Policy userPolicy =
   2603                 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
   2604         when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
   2605 
   2606         NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
   2607                 SUPPRESSED_EFFECT_NOTIFICATION_LIST);
   2608 
   2609         int expected = SUPPRESSED_EFFECT_BADGE;
   2610         int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
   2611 
   2612         assertEquals(expected, actual);
   2613     }
   2614 
   2615     @Test
   2616     public void testSetNotificationPolicy_preP_setOldNewFields() {
   2617         ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
   2618         mService.mZenModeHelper = mZenModeHelper;
   2619         NotificationManager.Policy userPolicy =
   2620                 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
   2621         when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
   2622 
   2623         NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
   2624                 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_STATUS_BAR);
   2625 
   2626         int expected =
   2627                 SUPPRESSED_EFFECT_BADGE | SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_PEEK;
   2628         int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
   2629 
   2630         assertEquals(expected, actual);
   2631     }
   2632 
   2633     @Test
   2634     public void testSetNotificationPolicy_P_setOldFields() {
   2635         ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
   2636         mService.mZenModeHelper = mZenModeHelper;
   2637         NotificationManager.Policy userPolicy =
   2638                 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
   2639         when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
   2640 
   2641         NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
   2642                 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF);
   2643 
   2644         int expected = SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF
   2645                 | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_AMBIENT
   2646                 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
   2647         int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
   2648 
   2649         assertEquals(expected, actual);
   2650     }
   2651 
   2652     @Test
   2653     public void testSetNotificationPolicy_P_setNewFields() {
   2654         ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
   2655         mService.mZenModeHelper = mZenModeHelper;
   2656         NotificationManager.Policy userPolicy =
   2657                 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
   2658         when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
   2659 
   2660         NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
   2661                 SUPPRESSED_EFFECT_NOTIFICATION_LIST | SUPPRESSED_EFFECT_AMBIENT
   2662                         | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT);
   2663 
   2664         int expected = SUPPRESSED_EFFECT_NOTIFICATION_LIST | SUPPRESSED_EFFECT_SCREEN_OFF
   2665                 | SUPPRESSED_EFFECT_AMBIENT | SUPPRESSED_EFFECT_LIGHTS
   2666                 | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
   2667         int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
   2668 
   2669         assertEquals(expected, actual);
   2670     }
   2671 
   2672     @Test
   2673     public void testSetNotificationPolicy_P_setOldNewFields() {
   2674         ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
   2675         mService.mZenModeHelper = mZenModeHelper;
   2676         NotificationManager.Policy userPolicy =
   2677                 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
   2678         when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
   2679 
   2680         NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
   2681                 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_STATUS_BAR);
   2682 
   2683         int expected =  SUPPRESSED_EFFECT_STATUS_BAR;
   2684         int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
   2685 
   2686         assertEquals(expected, actual);
   2687 
   2688         appPolicy = new NotificationManager.Policy(0, 0, 0,
   2689                 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_AMBIENT
   2690                         | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT);
   2691 
   2692         expected =  SUPPRESSED_EFFECT_SCREEN_OFF | SUPPRESSED_EFFECT_AMBIENT
   2693                 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
   2694         actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
   2695 
   2696         assertEquals(expected, actual);
   2697     }
   2698 
   2699     @Test
   2700     public void testVisualDifference_foreground() {
   2701         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2702                 .setContentTitle("foo");
   2703         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2704                 nb1.build(), new UserHandle(mUid), null, 0);
   2705         NotificationRecord r1 =
   2706                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2707 
   2708         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2709                 .setFlag(FLAG_FOREGROUND_SERVICE, true)
   2710                 .setContentTitle("bar");
   2711         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2712                 nb2.build(), new UserHandle(mUid), null, 0);
   2713         NotificationRecord r2 =
   2714                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2715 
   2716         assertFalse(mService.isVisuallyInterruptive(r1, r2));
   2717     }
   2718 
   2719     @Test
   2720     public void testVisualDifference_diffTitle() {
   2721         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2722                 .setContentTitle("foo");
   2723         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2724                 nb1.build(), new UserHandle(mUid), null, 0);
   2725         NotificationRecord r1 =
   2726                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2727 
   2728         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2729                 .setContentTitle("bar");
   2730         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2731                 nb2.build(), new UserHandle(mUid), null, 0);
   2732         NotificationRecord r2 =
   2733                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2734 
   2735         assertTrue(mService.isVisuallyInterruptive(r1, r2));
   2736     }
   2737 
   2738     @Test
   2739     public void testVisualDifference_inboxStyle() {
   2740         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2741                 .setStyle(new Notification.InboxStyle()
   2742                     .addLine("line1").addLine("line2"));
   2743         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2744                 nb1.build(), new UserHandle(mUid), null, 0);
   2745         NotificationRecord r1 =
   2746                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2747 
   2748         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2749                 .setStyle(new Notification.InboxStyle()
   2750                         .addLine("line1").addLine("line2_changed"));
   2751         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2752                 nb2.build(), new UserHandle(mUid), null, 0);
   2753         NotificationRecord r2 =
   2754                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2755 
   2756         assertTrue(mService.isVisuallyInterruptive(r1, r2)); // line 2 changed unnoticed
   2757 
   2758         Notification.Builder nb3 = new Notification.Builder(mContext, "")
   2759                 .setStyle(new Notification.InboxStyle()
   2760                         .addLine("line1"));
   2761         StatusBarNotification sbn3 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2762                 nb3.build(), new UserHandle(mUid), null, 0);
   2763         NotificationRecord r3 =
   2764                 new NotificationRecord(mContext, sbn3, mock(NotificationChannel.class));
   2765 
   2766         assertTrue(mService.isVisuallyInterruptive(r1, r3)); // line 2 removed unnoticed
   2767 
   2768         Notification.Builder nb4 = new Notification.Builder(mContext, "")
   2769                 .setStyle(new Notification.InboxStyle()
   2770                         .addLine("line1").addLine("line2").addLine("line3"));
   2771         StatusBarNotification sbn4 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2772                 nb4.build(), new UserHandle(mUid), null, 0);
   2773         NotificationRecord r4 =
   2774                 new NotificationRecord(mContext, sbn4, mock(NotificationChannel.class));
   2775 
   2776         assertTrue(mService.isVisuallyInterruptive(r1, r4)); // line 3 added unnoticed
   2777 
   2778         Notification.Builder nb5 = new Notification.Builder(mContext, "")
   2779             .setContentText("not an inbox");
   2780         StatusBarNotification sbn5 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2781                 nb5.build(), new UserHandle(mUid), null, 0);
   2782         NotificationRecord r5 =
   2783                 new NotificationRecord(mContext, sbn5, mock(NotificationChannel.class));
   2784 
   2785         assertTrue(mService.isVisuallyInterruptive(r1, r5)); // changed Styles, went unnoticed
   2786     }
   2787 
   2788     @Test
   2789     public void testVisualDifference_diffText() {
   2790         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2791                 .setContentText("foo");
   2792         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2793                 nb1.build(), new UserHandle(mUid), null, 0);
   2794         NotificationRecord r1 =
   2795                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2796 
   2797         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2798                 .setContentText("bar");
   2799         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2800                 nb2.build(), new UserHandle(mUid), null, 0);
   2801         NotificationRecord r2 =
   2802                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2803 
   2804         assertTrue(mService.isVisuallyInterruptive(r1, r2));
   2805     }
   2806 
   2807     @Test
   2808     public void testVisualDifference_sameText() {
   2809         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2810                 .setContentText("foo");
   2811         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2812                 nb1.build(), new UserHandle(mUid), null, 0);
   2813         NotificationRecord r1 =
   2814                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2815 
   2816         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2817                 .setContentText("foo");
   2818         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2819                 nb2.build(), new UserHandle(mUid), null, 0);
   2820         NotificationRecord r2 =
   2821                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2822 
   2823         assertFalse(mService.isVisuallyInterruptive(r1, r2));
   2824     }
   2825 
   2826     @Test
   2827     public void testVisualDifference_sameTextButStyled() {
   2828         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2829                 .setContentText(Html.fromHtml("<b>foo</b>"));
   2830         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2831                 nb1.build(), new UserHandle(mUid), null, 0);
   2832         NotificationRecord r1 =
   2833                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2834 
   2835         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2836                 .setContentText(Html.fromHtml("<b>foo</b>"));
   2837         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2838                 nb2.build(), new UserHandle(mUid), null, 0);
   2839         NotificationRecord r2 =
   2840                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2841 
   2842         assertFalse(mService.isVisuallyInterruptive(r1, r2));
   2843     }
   2844 
   2845     @Test
   2846     public void testVisualDifference_diffTextButStyled() {
   2847         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2848                 .setContentText(Html.fromHtml("<b>foo</b>"));
   2849         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2850                 nb1.build(), new UserHandle(mUid), null, 0);
   2851         NotificationRecord r1 =
   2852                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2853 
   2854         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2855                 .setContentText(Html.fromHtml("<b>bar</b>"));
   2856         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2857                 nb2.build(), new UserHandle(mUid), null, 0);
   2858         NotificationRecord r2 =
   2859                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2860 
   2861         assertTrue(mService.isVisuallyInterruptive(r1, r2));
   2862     }
   2863 
   2864     @Test
   2865     public void testVisualDifference_diffProgress() {
   2866         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2867                 .setProgress(100, 90, false);
   2868         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2869                 nb1.build(), new UserHandle(mUid), null, 0);
   2870         NotificationRecord r1 =
   2871                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2872 
   2873         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2874                 .setProgress(100, 100, false);
   2875         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2876                 nb2.build(), new UserHandle(mUid), null, 0);
   2877         NotificationRecord r2 =
   2878                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2879 
   2880         assertTrue(mService.isVisuallyInterruptive(r1, r2));
   2881     }
   2882 
   2883     @Test
   2884     public void testVisualDifference_diffProgressNotDone() {
   2885         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2886                 .setProgress(100, 90, false);
   2887         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2888                 nb1.build(), new UserHandle(mUid), null, 0);
   2889         NotificationRecord r1 =
   2890                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2891 
   2892         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2893                 .setProgress(100, 91, false);
   2894         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2895                 nb2.build(), new UserHandle(mUid), null, 0);
   2896         NotificationRecord r2 =
   2897                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2898 
   2899         assertFalse(mService.isVisuallyInterruptive(r1, r2));
   2900     }
   2901 
   2902     @Test
   2903     public void testVisualDifference_sameProgressStillDone() {
   2904         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2905                 .setProgress(100, 100, false);
   2906         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2907                 nb1.build(), new UserHandle(mUid), null, 0);
   2908         NotificationRecord r1 =
   2909                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2910 
   2911         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2912                 .setProgress(100, 100, false);
   2913         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2914                 nb2.build(), new UserHandle(mUid), null, 0);
   2915         NotificationRecord r2 =
   2916                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2917 
   2918         assertFalse(mService.isVisuallyInterruptive(r1, r2));
   2919     }
   2920 
   2921     @Test
   2922     public void testVisualDifference_summary() {
   2923         Notification.Builder nb1 = new Notification.Builder(mContext, "")
   2924                 .setGroup("bananas")
   2925                 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
   2926                 .setContentText("foo");
   2927         StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2928                 nb1.build(), new UserHandle(mUid), null, 0);
   2929         NotificationRecord r1 =
   2930                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
   2931 
   2932         Notification.Builder nb2 = new Notification.Builder(mContext, "")
   2933                 .setGroup("bananas")
   2934                 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
   2935                 .setContentText("bar");
   2936         StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
   2937                 nb2.build(), new UserHandle(mUid), null, 0);
   2938         NotificationRecord r2 =
   2939                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
   2940 
   2941         assertFalse(mService.isVisuallyInterruptive(r1, r2));
   2942     }
   2943 
   2944     @Test
   2945     public void testHideAndUnhideNotificationsOnSuspendedPackageBroadcast() {
   2946         // post 2 notification from this package
   2947         final NotificationRecord notif1 = generateNotificationRecord(
   2948                 mTestNotificationChannel, 1, null, true);
   2949         final NotificationRecord notif2 = generateNotificationRecord(
   2950                 mTestNotificationChannel, 2, null, false);
   2951         mService.addNotification(notif1);
   2952         mService.addNotification(notif2);
   2953 
   2954         // on broadcast, hide the 2 notifications
   2955         mService.simulatePackageSuspendBroadcast(true, PKG);
   2956         ArgumentCaptor<List> captorHide = ArgumentCaptor.forClass(List.class);
   2957         verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
   2958         assertEquals(2, captorHide.getValue().size());
   2959 
   2960         // on broadcast, unhide the 2 notifications
   2961         mService.simulatePackageSuspendBroadcast(false, PKG);
   2962         ArgumentCaptor<List> captorUnhide = ArgumentCaptor.forClass(List.class);
   2963         verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
   2964         assertEquals(2, captorUnhide.getValue().size());
   2965     }
   2966 
   2967     @Test
   2968     public void testNoNotificationsHiddenOnSuspendedPackageBroadcast() {
   2969         // post 2 notification from this package
   2970         final NotificationRecord notif1 = generateNotificationRecord(
   2971                 mTestNotificationChannel, 1, null, true);
   2972         final NotificationRecord notif2 = generateNotificationRecord(
   2973                 mTestNotificationChannel, 2, null, false);
   2974         mService.addNotification(notif1);
   2975         mService.addNotification(notif2);
   2976 
   2977         // on broadcast, nothing is hidden since no notifications are of package "test_package"
   2978         mService.simulatePackageSuspendBroadcast(true, "test_package");
   2979         ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
   2980         verify(mListeners, times(1)).notifyHiddenLocked(captor.capture());
   2981         assertEquals(0, captor.getValue().size());
   2982     }
   2983 
   2984     @Test
   2985     public void testCanUseManagedServicesLowRamNoWatchNullPkg() {
   2986         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
   2987         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   2988         when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
   2989                 .thenReturn(new String[] {"a", "b", "c"});
   2990         when(mContext.getResources()).thenReturn(mResources);
   2991 
   2992         assertEquals(false, mService.canUseManagedServices(null));
   2993     }
   2994 
   2995     @Test
   2996     public void testCanUseManagedServicesLowRamNoWatchValidPkg() {
   2997         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
   2998         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   2999         when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
   3000                 .thenReturn(new String[] {"a", "b", "c"});
   3001         when(mContext.getResources()).thenReturn(mResources);
   3002 
   3003         assertEquals(true, mService.canUseManagedServices("b"));
   3004     }
   3005 
   3006     @Test
   3007     public void testCanUseManagedServicesLowRamNoWatchNoValidPkg() {
   3008         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
   3009         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   3010         when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
   3011                 .thenReturn(new String[] {"a", "b", "c"});
   3012         when(mContext.getResources()).thenReturn(mResources);
   3013 
   3014         assertEquals(false, mService.canUseManagedServices("d"));
   3015     }
   3016 
   3017     @Test
   3018     public void testCanUseManagedServicesLowRamWatchNoValidPkg() {
   3019         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
   3020         when(mActivityManager.isLowRamDevice()).thenReturn(true);
   3021         when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
   3022                 .thenReturn(new String[] {"a", "b", "c"});
   3023         when(mContext.getResources()).thenReturn(mResources);
   3024 
   3025         assertEquals(true, mService.canUseManagedServices("d"));
   3026     }
   3027 
   3028     @Test
   3029     public void testCanUseManagedServicesNoLowRamNoWatchValidPkg() {
   3030         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
   3031         when(mActivityManager.isLowRamDevice()).thenReturn(false);
   3032         when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
   3033                 .thenReturn(new String[] {"a", "b", "c"});
   3034         when(mContext.getResources()).thenReturn(mResources);
   3035 
   3036         assertEquals(true, mService.canUseManagedServices("d"));
   3037     }
   3038 
   3039     @Test
   3040     public void testCanUseManagedServicesNoLowRamWatchValidPkg() {
   3041         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
   3042         when(mActivityManager.isLowRamDevice()).thenReturn(false);
   3043         when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
   3044                 .thenReturn(new String[] {"a", "b", "c"});
   3045         when(mContext.getResources()).thenReturn(mResources);
   3046 
   3047         assertEquals(true, mService.canUseManagedServices("d"));
   3048     }
   3049 
   3050     @Test
   3051     public void testOnNotificationVisibilityChanged_triggersInterruptionUsageStat() {
   3052         final NotificationRecord r = generateNotificationRecord(
   3053                 mTestNotificationChannel, 1, null, true);
   3054         r.setTextChanged(true);
   3055         mService.addNotification(r);
   3056 
   3057         mService.mNotificationDelegate.onNotificationVisibilityChanged(new NotificationVisibility[]
   3058                 {NotificationVisibility.obtain(r.getKey(), 1, 1, true)},
   3059                 new NotificationVisibility[]{});
   3060 
   3061         verify(mAppUsageStats).reportInterruptiveNotification(anyString(), anyString(), anyInt());
   3062     }
   3063 
   3064     @Test
   3065     public void testSetNotificationsShownFromListener_triggersInterruptionUsageStat()
   3066             throws RemoteException {
   3067         final NotificationRecord r = generateNotificationRecord(
   3068                 mTestNotificationChannel, 1, null, true);
   3069         r.setTextChanged(true);
   3070         mService.addNotification(r);
   3071 
   3072         mBinderService.setNotificationsShownFromListener(null, new String[] {r.getKey()});
   3073 
   3074         verify(mAppUsageStats).reportInterruptiveNotification(anyString(), anyString(), anyInt());
   3075     }
   3076 
   3077     @Test
   3078     public void testMybeRecordInterruptionLocked_doesNotRecordTwice()
   3079             throws RemoteException {
   3080         final NotificationRecord r = generateNotificationRecord(
   3081                 mTestNotificationChannel, 1, null, true);
   3082         r.setInterruptive(true);
   3083         mService.addNotification(r);
   3084 
   3085         mService.maybeRecordInterruptionLocked(r);
   3086         mService.maybeRecordInterruptionLocked(r);
   3087 
   3088         verify(mAppUsageStats, times(1)).reportInterruptiveNotification(
   3089                 anyString(), anyString(), anyInt());
   3090     }
   3091 }
   3092