blob: cdbf3c66767b9f82ad4637d1b7f94d3f6b249abb [file] [log] [blame]
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -05001/*
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
17package com.android.server.notification;
18
Julia Reynoldse5c60452018-04-30 14:41:36 -040019import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -050020import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040021import static android.app.NotificationManager.IMPORTANCE_HIGH;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040022import static android.app.NotificationManager.IMPORTANCE_LOW;
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -050023import static android.app.NotificationManager.IMPORTANCE_MAX;
Julia Reynolds4da79702017-06-01 11:06:10 -040024import static android.app.NotificationManager.IMPORTANCE_NONE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040025import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -050026import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
27import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
28import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
29import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
30import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
31import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
32import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
33import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
34import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
Julia Reynoldse1816412017-10-24 10:39:11 -040035import static android.content.pm.PackageManager.FEATURE_WATCH;
Julia Reynolds4db59552017-06-30 13:34:01 -040036import static android.content.pm.PackageManager.PERMISSION_DENIED;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -050037import static android.os.Build.VERSION_CODES.O_MR1;
38import static android.os.Build.VERSION_CODES.P;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040039
Geoffrey Pitsch03533712017-01-05 10:30:07 -050040import static junit.framework.Assert.assertEquals;
Julia Reynolds727a7282017-04-13 10:54:01 -040041import static junit.framework.Assert.assertFalse;
Julia Reynolds92febc32017-10-26 11:30:31 -040042import static junit.framework.Assert.assertNotNull;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040043import static junit.framework.Assert.assertNull;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050044import static junit.framework.Assert.assertTrue;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050045import static junit.framework.Assert.fail;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050046
Julia Reynolds5f20e9f2017-01-30 08:54:53 -050047import static org.mockito.Matchers.anyBoolean;
Julia Reynoldsa78cdff2017-04-26 10:19:25 -040048import static org.mockito.Matchers.anyLong;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050049import static org.mockito.Matchers.anyString;
50import static org.mockito.Matchers.eq;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050051import static org.mockito.Mockito.any;
52import static org.mockito.Mockito.anyInt;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040053import static org.mockito.Mockito.atLeastOnce;
Julia Reynoldseb3dca72017-07-11 10:39:58 -040054import static org.mockito.Mockito.doAnswer;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050055import static org.mockito.Mockito.mock;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040056import static org.mockito.Mockito.never;
57import static org.mockito.Mockito.reset;
Julia Reynolds503ed942017-10-04 16:04:56 -040058import static org.mockito.Mockito.spy;
59import static org.mockito.Mockito.timeout;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050060import static org.mockito.Mockito.times;
61import static org.mockito.Mockito.verify;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050062import static org.mockito.Mockito.when;
63
Julia Reynolds68263d12017-06-21 14:21:19 -040064import android.app.ActivityManager;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040065import android.app.IActivityManager;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050066import android.app.INotificationManager;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050067import android.app.Notification;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040068import android.app.Notification.MessagingStyle.Message;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050069import android.app.NotificationChannel;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040070import android.app.NotificationChannelGroup;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050071import android.app.NotificationManager;
Jason Parks50322ff2018-03-27 10:23:33 -050072import android.app.admin.DeviceAdminInfo;
73import android.app.admin.DevicePolicyManagerInternal;
Julia Reynolds7217dc92018-03-07 12:12:09 -050074import android.app.usage.UsageStatsManagerInternal;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040075import android.companion.ICompanionDeviceManager;
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -050076import android.content.ComponentName;
Jeff Sharkey6a97cc32018-04-17 12:16:20 -060077import android.content.ContentUris;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050078import android.content.Context;
Beverlyd4f96492017-08-02 13:36:11 -040079import android.content.Intent;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050080import android.content.pm.ApplicationInfo;
81import android.content.pm.IPackageManager;
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -050082import android.content.pm.PackageManager;
Geoffrey Pitsch03533712017-01-05 10:30:07 -050083import android.content.pm.ParceledListSlice;
Kristian Monsen30f59b22018-04-09 10:27:16 +020084import android.content.res.Resources;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040085import android.graphics.Color;
Jeff Sharkey6a97cc32018-04-17 12:16:20 -060086import android.media.AudioAttributes;
Julia Reynolds76c096d2017-06-19 08:16:04 -040087import android.media.AudioManager;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040088import android.net.Uri;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050089import android.os.Binder;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040090import android.os.Build;
Julia Reynolds503ed942017-10-04 16:04:56 -040091import android.os.Bundle;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040092import android.os.IBinder;
Julia Reynoldsf27d6b22017-04-13 15:48:16 -040093import android.os.Process;
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -040094import android.os.RemoteException;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050095import android.os.UserHandle;
Jeff Sharkey6a97cc32018-04-17 12:16:20 -060096import android.provider.MediaStore;
Chris Wren89aa2262017-05-05 18:05:56 -040097import android.provider.Settings.Secure;
Julia Reynolds503ed942017-10-04 16:04:56 -040098import android.service.notification.Adjustment;
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -040099import android.service.notification.INotificationListener;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400100import android.service.notification.NotificationListenerService;
Julia Reynolds503ed942017-10-04 16:04:56 -0400101import android.service.notification.NotificationStats;
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500102import android.service.notification.NotifyingApp;
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500103import android.service.notification.StatusBarNotification;
Geoffrey Pitsch8185d382017-05-19 18:41:32 -0400104import android.test.suitebuilder.annotation.SmallTest;
Jason Monk745d0a82017-04-17 11:34:22 -0400105import android.testing.AndroidTestingRunner;
Julia Reynolds92febc32017-10-26 11:30:31 -0400106import android.testing.TestableContext;
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400107import android.testing.TestableLooper;
Jason Monk745d0a82017-04-17 11:34:22 -0400108import android.testing.TestableLooper.RunWithLooper;
Dan Sandler7d67bd42018-05-15 14:06:38 -0400109import android.text.Html;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400110import android.util.ArrayMap;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400111import android.util.AtomicFile;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400112
Kristian Monsen30f59b22018-04-09 10:27:16 +0200113import com.android.internal.R;
Julia Reynolds503ed942017-10-04 16:04:56 -0400114import com.android.internal.statusbar.NotificationVisibility;
Jason Monk74f5e362017-12-06 08:56:33 -0500115import com.android.server.UiServiceTestCase;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400116import com.android.server.lights.Light;
117import com.android.server.lights.LightsManager;
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400118import com.android.server.notification.NotificationManagerService.NotificationAssistants;
119import com.android.server.notification.NotificationManagerService.NotificationListeners;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400120
121import org.junit.After;
122import org.junit.Before;
123import org.junit.Test;
124import org.junit.runner.RunWith;
Julia Reynolds40f00d72017-12-12 10:47:32 -0500125import org.mockito.ArgumentCaptor;
126import org.mockito.Mock;
127import org.mockito.MockitoAnnotations;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400128import org.mockito.stubbing.Answer;
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500129
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400130import java.io.BufferedInputStream;
131import java.io.ByteArrayInputStream;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400132import java.io.File;
133import java.io.FileInputStream;
134import java.io.FileOutputStream;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400135import java.util.ArrayList;
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500136import java.util.Arrays;
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500137import java.util.HashSet;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400138import java.util.List;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400139import java.util.Map;
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500140import java.util.Set;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500141
Geoffrey Pitsch8185d382017-05-19 18:41:32 -0400142@SmallTest
Jason Monk745d0a82017-04-17 11:34:22 -0400143@RunWith(AndroidTestingRunner.class)
144@RunWithLooper
Jason Monk74f5e362017-12-06 08:56:33 -0500145public class NotificationManagerServiceTest extends UiServiceTestCase {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500146 private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400147 private final int mUid = Binder.getCallingUid();
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500148 private TestableNotificationManagerService mService;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500149 private INotificationManager mBinderService;
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400150 private NotificationManagerInternal mInternalService;
Julia Reynoldsda781472017-04-12 09:41:16 -0400151 @Mock
152 private IPackageManager mPackageManager;
153 @Mock
154 private PackageManager mPackageManagerClient;
Julia Reynolds92febc32017-10-26 11:30:31 -0400155 private TestableContext mContext = spy(getContext());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500156 private final String PKG = mContext.getPackageName();
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400157 private TestableLooper mTestableLooper;
Julia Reynoldsda781472017-04-12 09:41:16 -0400158 @Mock
159 private RankingHelper mRankingHelper;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400160 AtomicFile mPolicyFile;
161 File mFile;
162 @Mock
Geoffrey Pitschd5bcf212017-06-01 15:45:35 -0400163 private NotificationUsageStats mUsageStats;
Julia Reynolds76c096d2017-06-19 08:16:04 -0400164 @Mock
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -0400165 private UsageStatsManagerInternal mAppUsageStats;
166 @Mock
Julia Reynolds76c096d2017-06-19 08:16:04 -0400167 private AudioManager mAudioManager;
Julia Reynolds68263d12017-06-21 14:21:19 -0400168 @Mock
169 ActivityManager mActivityManager;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400170 NotificationManagerService.WorkerHandler mHandler;
Kristian Monsen30f59b22018-04-09 10:27:16 +0200171 @Mock
172 Resources mResources;
Julia Reynolds3ff26d22017-06-19 08:16:04 -0400173
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500174 private NotificationChannel mTestNotificationChannel = new NotificationChannel(
175 TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
Julia Reynoldsda781472017-04-12 09:41:16 -0400176 @Mock
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400177 private NotificationListeners mListeners;
178 @Mock private NotificationAssistants mAssistants;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400179 @Mock private ConditionProviders mConditionProviders;
Julia Reynoldsda781472017-04-12 09:41:16 -0400180 private ManagedServices.ManagedServiceInfo mListener;
181 @Mock private ICompanionDeviceManager mCompanionMgr;
Julia Reynoldsa78cdff2017-04-26 10:19:25 -0400182 @Mock SnoozeHelper mSnoozeHelper;
Julia Reynolds8aebf352017-06-26 11:35:33 -0400183 @Mock GroupHelper mGroupHelper;
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400184 @Mock
185 IBinder mPermOwner;
186 @Mock
187 IActivityManager mAm;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500188
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400189 // Use a Testable subclass so we can simulate calls from the system without failing.
190 private static class TestableNotificationManagerService extends NotificationManagerService {
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500191 int countSystemChecks = 0;
192
Amith Yamasani803eab692017-11-09 17:47:04 -0800193 public TestableNotificationManagerService(Context context) {
194 super(context);
195 }
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400196
197 @Override
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400198 protected boolean isCallingUidSystem() {
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500199 countSystemChecks++;
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400200 return true;
201 }
202
203 @Override
204 protected boolean isCallerSystemOrPhone() {
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500205 countSystemChecks++;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400206 return true;
207 }
Julia Reynolds727a7282017-04-13 10:54:01 -0400208
209 @Override
210 protected ICompanionDeviceManager getCompanionManager() {
211 return null;
212 }
Amith Yamasani803eab692017-11-09 17:47:04 -0800213
214 @Override
215 protected void reportSeen(NotificationRecord r) {
216 return;
217 }
Amith Yamasani7ec89412018-02-07 08:48:49 -0800218
219 @Override
220 protected void reportUserInteraction(NotificationRecord r) {
221 return;
222 }
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400223 }
224
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500225 @Before
226 public void setUp() throws Exception {
Julia Reynoldsda781472017-04-12 09:41:16 -0400227 MockitoAnnotations.initMocks(this);
Chris Wren89aa2262017-05-05 18:05:56 -0400228
229 // most tests assume badging is enabled
230 Secure.putIntForUser(getContext().getContentResolver(),
231 Secure.NOTIFICATION_BADGING, 1,
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400232 UserHandle.getUserHandleForUid(mUid).getIdentifier());
Chris Wren89aa2262017-05-05 18:05:56 -0400233
Julia Reynolds503ed942017-10-04 16:04:56 -0400234 mService = new TestableNotificationManagerService(mContext);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500235
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400236 // Use this testable looper.
237 mTestableLooper = TestableLooper.get(this);
Julia Reynolds503ed942017-10-04 16:04:56 -0400238 mHandler = mService.new WorkerHandler(mTestableLooper.getLooper());
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500239 // MockPackageManager - default returns ApplicationInfo with matching calling UID
Julia Reynolds92febc32017-10-26 11:30:31 -0400240 mContext.setMockPackageManager(mPackageManagerClient);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500241 final ApplicationInfo applicationInfo = new ApplicationInfo();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400242 applicationInfo.uid = mUid;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400243 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500244 .thenReturn(applicationInfo);
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500245 when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500246 .thenReturn(applicationInfo);
Julia Reynolds92febc32017-10-26 11:30:31 -0400247 when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid);
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500248 final LightsManager mockLightsManager = mock(LightsManager.class);
249 when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
Julia Reynolds76c096d2017-06-19 08:16:04 -0400250 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
Julia Reynoldse1816412017-10-24 10:39:11 -0400251 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400252 when(mAm.newUriPermissionOwner(anyString())).thenReturn(mPermOwner);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500253
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400254 // write to a test file; the system file isn't readable from tests
Julia Reynoldsb852e562017-06-06 16:14:18 -0400255 mFile = new File(mContext.getCacheDir(), "test.xml");
256 mFile.createNewFile();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400257 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);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400263
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400264 // Setup managed services
265 mListener = mListeners.new ManagedServiceInfo(
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400266 null, new ComponentName(PKG, "test_class"), mUid, true, null, 0);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400267 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
Julia Reynoldsb852e562017-06-06 16:14:18 -0400278 try {
Julia Reynolds503ed942017-10-04 16:04:56 -0400279 mService.init(mTestableLooper.getLooper(),
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400280 mPackageManager, mPackageManagerClient, mockLightsManager,
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400281 mListeners, mAssistants, mConditionProviders,
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400282 mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -0400283 mGroupHelper, mAm, mAppUsageStats,
Jason Parks50322ff2018-03-27 10:23:33 -0500284 mock(DevicePolicyManagerInternal.class));
Julia Reynoldsb852e562017-06-06 16:14:18 -0400285 } catch (SecurityException e) {
286 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
287 throw e;
288 }
289 }
Julia Reynolds503ed942017-10-04 16:04:56 -0400290 mService.setAudioManager(mAudioManager);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500291
292 // Tests call directly into the Binder.
Julia Reynolds503ed942017-10-04 16:04:56 -0400293 mBinderService = mService.getBinderService();
294 mInternalService = mService.getInternalService();
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500295
296 mBinderService.createNotificationChannels(
297 PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel)));
Julia Reynolds92febc32017-10-26 11:30:31 -0400298 assertNotNull(mBinderService.getNotificationChannel(PKG, TEST_CHANNEL_ID));
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500299 }
300
Julia Reynoldsb852e562017-06-06 16:14:18 -0400301 @After
302 public void tearDown() throws Exception {
303 mFile.delete();
304 }
305
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500306 public void waitForIdle() {
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400307 mTestableLooper.processAllMessages();
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500308 }
309
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500310 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
Julia Reynoldsa78cdff2017-04-26 10:19:25 -0400319 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
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400327 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
328 nb.build(), new UserHandle(mUid), null, 0);
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000329 return new NotificationRecord(mContext, sbn, channel);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -0400330 }
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400331
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500332 private NotificationRecord generateNotificationRecord(NotificationChannel channel) {
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500333 return generateNotificationRecord(channel, null);
334 }
335
336 private NotificationRecord generateNotificationRecord(NotificationChannel channel,
337 Notification.TvExtender extender) {
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500338 if (channel == null) {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500339 channel = mTestNotificationChannel;
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500340 }
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500341 Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500342 .setContentTitle("foo")
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500343 .setSmallIcon(android.R.drawable.sym_def_app_icon);
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500344 if (extender != null) {
345 nb.extend(extender);
346 }
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400347 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
348 nb.build(), new UserHandle(mUid), null, 0);
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000349 return new NotificationRecord(mContext, sbn, channel);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500350 }
351
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400352 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
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500389 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500390 public void testCreateNotificationChannels_SingleChannel() throws Exception {
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500391 final NotificationChannel channel =
392 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400393 mBinderService.createNotificationChannels(PKG,
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500394 new ParceledListSlice(Arrays.asList(channel)));
395 final NotificationChannel createdChannel =
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400396 mBinderService.getNotificationChannel(PKG, "id");
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500397 assertTrue(createdChannel != null);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500398 }
399
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500400 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500401 public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception {
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500402 try {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400403 mBinderService.createNotificationChannels(PKG,
Kristian Monsen30f59b22018-04-09 10:27:16 +0200404 new ParceledListSlice(Arrays.asList((Object[])null)));
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500405 fail("Exception should be thrown immediately.");
406 } catch (NullPointerException e) {
407 // pass
408 }
409 }
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500410
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500411 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500412 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);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400417 mBinderService.createNotificationChannels(PKG,
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500418 new ParceledListSlice(Arrays.asList(channel1, channel2)));
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400419 assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null);
420 assertTrue(mBinderService.getNotificationChannel(PKG, "id2") != null);
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500421 }
422
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500423 @Test
Geoffrey Pitsch76a3aa02017-07-26 15:07:34 -0400424 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 =
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400433 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
Geoffrey Pitsch76a3aa02017-07-26 15:07:34 -0400434 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
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400460 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 =
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400469 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400470 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");
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400479 assertEquals(IMPORTANCE_HIGH, createdChannel.getImportance());
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400480 }
481
482 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500483 public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond()
484 throws Exception {
485 final NotificationChannel channel1 =
486 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
487 final NotificationChannel channel2 =
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400488 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400489 mBinderService.createNotificationChannels(PKG,
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500490 new ParceledListSlice(Arrays.asList(channel1, channel2)));
491 final NotificationChannel createdChannel =
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400492 mBinderService.getNotificationChannel(PKG, "id");
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500493 assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
494 }
495
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500496 @Test
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500497 public void testBlockedNotifications_suspended() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500498 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(true);
499
500 NotificationChannel channel = new NotificationChannel("id", "name",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400501 IMPORTANCE_HIGH);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500502 NotificationRecord r = generateNotificationRecord(channel);
Julia Reynolds503ed942017-10-04 16:04:56 -0400503 assertTrue(mService.isBlocked(r, mUsageStats));
Geoffrey Pitschd5bcf212017-06-01 15:45:35 -0400504 verify(mUsageStats, times(1)).registerSuspendedByAdmin(eq(r));
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500505 }
506
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500507 @Test
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500508 public void testBlockedNotifications_blockedChannel() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500509 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
510
511 NotificationChannel channel = new NotificationChannel("id", "name",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400512 NotificationManager.IMPORTANCE_NONE);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500513 NotificationRecord r = generateNotificationRecord(channel);
Julia Reynolds503ed942017-10-04 16:04:56 -0400514 assertTrue(mService.isBlocked(r, mUsageStats));
Geoffrey Pitschd5bcf212017-06-01 15:45:35 -0400515 verify(mUsageStats, times(1)).registerBlocked(eq(r));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400516
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;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400537 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400538 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,
Julia Reynolds503ed942017-10-04 16:04:56 -0400543 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400544 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
Dianne Hackborn025d4a52018-04-30 16:23:26 -0700565 StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400566 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400567 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
568 sbn.getId(), sbn.getNotification(), sbn.getUserId());
569 waitForIdle();
Dianne Hackborn025d4a52018-04-30 16:23:26 -0700570 // 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.
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400593 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400594 assertNull(mService.getNotificationRecord(sbn.getKey()));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400595 assertEquals(IMPORTANCE_NONE,
596 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500597 }
598
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500599 @Test
Julia Reynolds005c8b92017-08-24 10:35:53 -0400600 public void testBlockedNotifications_blockedChannelGroup() throws Exception {
601 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
Julia Reynolds503ed942017-10-04 16:04:56 -0400602 mService.setRankingHelper(mRankingHelper);
Julia Reynolds005c8b92017-08-24 10:35:53 -0400603 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);
Julia Reynolds503ed942017-10-04 16:04:56 -0400609 assertTrue(mService.isBlocked(r, mUsageStats));
Julia Reynolds005c8b92017-08-24 10:35:53 -0400610 verify(mUsageStats, times(1)).registerBlocked(eq(r));
611 }
612
613 @Test
Julia Reynolds4da79702017-06-01 11:06:10 -0400614 public void testEnqueuedBlockedNotifications_blockedApp() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500615 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
616
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400617 mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
Julia Reynolds4da79702017-06-01 11:06:10 -0400618
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);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500624 }
625
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500626 @Test
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400627 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;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400633 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400634 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
635 sbn.getId(), sbn.getNotification(), sbn.getUserId());
636 waitForIdle();
637 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400638 assertNull(mService.getNotificationRecord(sbn.getKey()));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400639 }
640
641 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500642 public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500643 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400644 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500645 waitForIdle();
Julia Reynolds080361e2017-07-13 11:23:12 -0400646 StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500647 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400648 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500649 }
650
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500651 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500652 public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500653 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400654 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500655 mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500656 waitForIdle();
657 StatusBarNotification[] notifs =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500658 mBinderService.getActiveNotifications(PKG);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500659 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400660 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500661 }
662
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500663 @Test
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500664 public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500665 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400666 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500667 waitForIdle();
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500668 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400669 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500670 mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500671 waitForIdle();
672 StatusBarNotification[] notifs =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500673 mBinderService.getActiveNotifications(PKG);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500674 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400675 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());
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500679 }
680
681 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500682 public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -0400683 NotificationRecord r = generateNotificationRecord(null);
684 final StatusBarNotification sbn = r.sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500685 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400686 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500687 mBinderService.cancelNotificationsFromListener(null, null);
688 waitForIdle();
689 StatusBarNotification[] notifs =
690 mBinderService.getActiveNotifications(sbn.getPackageName());
691 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400692 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500693 }
694
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500695 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500696 public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
697 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500698 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400699 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500700 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500701 waitForIdle();
702 StatusBarNotification[] notifs =
703 mBinderService.getActiveNotifications(sbn.getPackageName());
704 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400705 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds080361e2017-07-13 11:23:12 -0400706 }
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
Julia Reynolds503ed942017-10-04 16:04:56 -0400717 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Julia Reynolds080361e2017-07-13 11:23:12 -0400718 n.getUserId());
719 waitForIdle();
720 StatusBarNotification[] notifs =
721 mBinderService.getActiveNotifications(n.sbn.getPackageName());
722 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400723 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());
Julia Reynolds080361e2017-07-13 11:23:12 -0400727 }
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();
Julia Reynolds503ed942017-10-04 16:04:56 -0400744 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500745 }
746
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500747 @Test
Julia Reynolds0839c022017-06-15 15:24:01 -0400748 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();
Julia Reynolds080361e2017-07-13 11:23:12 -0400756
Julia Reynolds503ed942017-10-04 16:04:56 -0400757 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds0839c022017-06-15 15:24:01 -0400758 }
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();
Julia Reynolds080361e2017-07-13 11:23:12 -0400784
Julia Reynolds503ed942017-10-04 16:04:56 -0400785 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds0839c022017-06-15 15:24:01 -0400786 }
787
788 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500789 public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
790 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400791 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500792 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400793 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500794 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500795 waitForIdle();
796 StatusBarNotification[] notifs =
797 mBinderService.getActiveNotifications(sbn.getPackageName());
798 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400799 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500800 }
801
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500802 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500803 public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
804 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400805 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500806 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400807 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500808 mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
809 waitForIdle();
810 StatusBarNotification[] notifs =
811 mBinderService.getActiveNotifications(sbn.getPackageName());
812 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400813 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500814 }
815
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500816 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500817 public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
818 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500819 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400820 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500821 mBinderService.cancelAllNotifications(null, sbn.getUserId());
822 waitForIdle();
823 StatusBarNotification[] notifs =
824 mBinderService.getActiveNotifications(sbn.getPackageName());
825 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400826 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500827 }
828
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500829 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500830 public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
831 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500832 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400833 sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500834 // 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);
Julia Reynolds503ed942017-10-04 16:04:56 -0400840 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500841 }
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500842
843 @Test
Beverly40239d92017-07-07 10:20:41 -0400844 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;
Julia Reynolds503ed942017-10-04 16:04:56 -0400861 mService.addNotification(notif);
862 mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true,
Beverly40239d92017-07-07 10:20:41 -0400863 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;
Julia Reynolds503ed942017-10-04 16:04:56 -0400875 mService.addNotification(notif);
Beverly40239d92017-07-07 10:20:41 -0400876
Julia Reynolds503ed942017-10-04 16:04:56 -0400877 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Beverly40239d92017-07-07 10:20:41 -0400878 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);
Julia Reynolds503ed942017-10-04 16:04:56 -0400896 mService.addNotification(parent);
897 mService.addNotification(child);
898 mService.addNotification(child2);
899 mService.addNotification(newGroup);
900 mService.getBinderService().cancelNotificationsFromListener(null, null);
Beverly40239d92017-07-07 10:20:41 -0400901 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);
Julia Reynolds503ed942017-10-04 16:04:56 -0400918 mService.addNotification(parent);
919 mService.addNotification(child);
920 mService.addNotification(child2);
921 mService.addNotification(newGroup);
922 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Beverly40239d92017-07-07 10:20:41 -0400923 parent.getUserId());
924 waitForIdle();
925 StatusBarNotification[] notifs =
926 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
927 assertEquals(1, notifs.length);
928 }
929
930 @Test
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400931 public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
932 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400933 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400934 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400935 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400936 mInternalService.removeForegroundServiceFlagFromNotification(PKG, sbn.getId(),
937 sbn.getUserId());
938 waitForIdle();
939 StatusBarNotification[] notifs =
940 mBinderService.getActiveNotifications(sbn.getPackageName());
Julia Reynoldse5c60452018-04-30 14:41:36 -0400941 assertEquals(0, notifs[0].getNotification().flags & FLAG_FOREGROUND_SERVICE);
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400942 }
943
944 @Test
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400945 public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception {
946 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
947 sbn.getNotification().flags =
Julia Reynoldse5c60452018-04-30 14:41:36 -0400948 Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400949 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);
Julia Reynolds503ed942017-10-04 16:04:56 -0400957 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400958 }
959
960 @Test
Julia Reynolds40f00d72017-12-12 10:47:32 -0500961 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);
Julia Reynoldse5c60452018-04-30 14:41:36 -0400969 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -0500970 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);
Julia Reynoldse5c60452018-04-30 14:41:36 -0400992 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -0500993 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);
Julia Reynoldse5c60452018-04-30 14:41:36 -04001016 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -05001017 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
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001032 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);
Julia Reynolds503ed942017-10-04 16:04:56 -04001036 mService.addEnqueuedNotification(group1);
1037 mService.addNotification(group1);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001038
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 =
Julia Reynolds503ed942017-10-04 16:04:56 -04001061 mService.findGroupNotificationsLocked(PKG, group1.getGroupKey(),
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001062 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
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001070 @Test
Julia Reynolds40f00d72017-12-12 10:47:32 -05001071 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
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001222 public void testTvExtenderChannelOverride_onTv() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001223 mService.setIsTelevision(true);
1224 mService.setRankingHelper(mRankingHelper);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001225 when(mRankingHelper.getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001226 anyString(), anyInt(), eq("foo"), anyBoolean())).thenReturn(
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001227 new NotificationChannel("foo", "foo", IMPORTANCE_HIGH));
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001228
Julia Reynoldsbad42972017-04-25 13:52:49 -04001229 Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001230 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -04001231 generateNotificationRecord(null, tv).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001232 verify(mRankingHelper, times(1)).getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001233 anyString(), anyInt(), eq("foo"), anyBoolean());
1234 }
1235
1236 @Test
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001237 public void testTvExtenderChannelOverride_notOnTv() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001238 mService.setIsTelevision(false);
1239 mService.setRankingHelper(mRankingHelper);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001240 when(mRankingHelper.getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001241 anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001242 mTestNotificationChannel);
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001243
Julia Reynoldsbad42972017-04-25 13:52:49 -04001244 Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001245 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -04001246 generateNotificationRecord(null, tv).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001247 verify(mRankingHelper, times(1)).getNotificationChannel(
1248 anyString(), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean());
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001249 }
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001250
1251 @Test
Julia Reynoldsfc9767b2018-01-22 17:45:16 -05001252 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
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001280 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(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001298 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001299 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(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001320 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001321 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(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001356 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001357 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(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001377 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001378 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
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001394 public void testCreateChannelNotifyListener() throws Exception {
1395 List<String> associations = new ArrayList<>();
1396 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001397 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds503ed942017-10-04 16:04:56 -04001398 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001399 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
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001407 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001408 mBinderService.createNotificationChannels(PKG,
1409 new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001410 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001411 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001412 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001413 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001414 eq(Process.myUserHandle()), eq(channel2),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001415 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
1416 }
1417
1418 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001419 public void testCreateChannelGroupNotifyListener() throws Exception {
1420 List<String> associations = new ArrayList<>();
1421 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001422 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds503ed942017-10-04 16:04:56 -04001423 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001424 NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
1425 NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
1426
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001427 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001428 mBinderService.createNotificationChannelGroups(PKG,
1429 new ParceledListSlice(Arrays.asList(group1, group2)));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001430 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001431 eq(Process.myUserHandle()), eq(group1),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001432 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001433 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001434 eq(Process.myUserHandle()), eq(group2),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001435 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
1436 }
1437
1438 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001439 public void testUpdateChannelNotifyListener() throws Exception {
1440 List<String> associations = new ArrayList<>();
1441 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001442 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds503ed942017-10-04 16:04:56 -04001443 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001444 mTestNotificationChannel.setLightColor(Color.CYAN);
1445 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1446 eq(mTestNotificationChannel.getId()), anyBoolean()))
1447 .thenReturn(mTestNotificationChannel);
1448
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001449 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001450 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001451 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001452 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001453 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1454 }
1455
1456 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001457 public void testDeleteChannelNotifyListener() throws Exception {
1458 List<String> associations = new ArrayList<>();
1459 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001460 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds503ed942017-10-04 16:04:56 -04001461 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001462 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1463 eq(mTestNotificationChannel.getId()), anyBoolean()))
1464 .thenReturn(mTestNotificationChannel);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001465 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001466 mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001467 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001468 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001469 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
1470 }
1471
1472 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001473 public void testDeleteChannelGroupNotifyListener() throws Exception {
1474 List<String> associations = new ArrayList<>();
1475 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001476 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001477 NotificationChannelGroup ncg = new NotificationChannelGroup("a", "b/c");
Julia Reynolds503ed942017-10-04 16:04:56 -04001478 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001479 when(mRankingHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt()))
1480 .thenReturn(ncg);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001481 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001482 mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001483 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001484 eq(Process.myUserHandle()), eq(ncg),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001485 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
1486 }
1487
1488 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001489 public void testUpdateNotificationChannelFromPrivilegedListener_success() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001490 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001491 List<String> associations = new ArrayList<>();
1492 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001493 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001494 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1495 eq(mTestNotificationChannel.getId()), anyBoolean()))
1496 .thenReturn(mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001497
1498 mBinderService.updateNotificationChannelFromPrivilegedListener(
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001499 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001500
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001501 verify(mRankingHelper, times(1)).updateNotificationChannel(
1502 anyString(), anyInt(), any(), anyBoolean());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001503
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001504 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001505 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001506 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1507 }
1508
1509 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001510 public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001511 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001512 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001513 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001514
1515 try {
1516 mBinderService.updateNotificationChannelFromPrivilegedListener(
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001517 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001518 fail("listeners that don't have a companion device shouldn't be able to call this");
1519 } catch (SecurityException e) {
1520 // pass
1521 }
1522
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001523 verify(mRankingHelper, never()).updateNotificationChannel(
1524 anyString(), anyInt(), any(), anyBoolean());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001525
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001526 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001527 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
1528 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1529 }
1530
1531 @Test
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001532 public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001533 mService.setRankingHelper(mRankingHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001534 List<String> associations = new ArrayList<>();
1535 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001536 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001537 mListener = mock(ManagedServices.ManagedServiceInfo.class);
Julia Reynolds4da79702017-06-01 11:06:10 -04001538 mListener.component = new ComponentName(PKG, PKG);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001539 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001540 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001541
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
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001550 verify(mRankingHelper, never()).updateNotificationChannel(
1551 anyString(), anyInt(), any(), anyBoolean());
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001552
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001553 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001554 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001555 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1556 }
1557
1558 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001559 public void testGetNotificationChannelFromPrivilegedListener_success() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001560 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001561 List<String> associations = new ArrayList<>();
1562 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001563 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001564
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001565 mBinderService.getNotificationChannelsFromPrivilegedListener(
1566 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001567
1568 verify(mRankingHelper, times(1)).getNotificationChannels(
1569 anyString(), anyInt(), anyBoolean());
1570 }
1571
1572 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001573 public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001574 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001575 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001576 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001577
1578 try {
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001579 mBinderService.getNotificationChannelsFromPrivilegedListener(
1580 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001581 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
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001591 public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001592 mService.setRankingHelper(mRankingHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001593 List<String> associations = new ArrayList<>();
1594 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001595 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001596 mListener = mock(ManagedServices.ManagedServiceInfo.class);
1597 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001598 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001599
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
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001613 public void testGetNotificationChannelGroupsFromPrivilegedListener_success() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001614 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001615 List<String> associations = new ArrayList<>();
1616 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001617 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001618
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001619 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1620 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001621
1622 verify(mRankingHelper, times(1)).getNotificationChannelGroups(anyString(), anyInt());
1623 }
1624
1625 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001626 public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001627 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001628 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001629 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001630
1631 try {
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001632 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
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001643 public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001644 mService.setRankingHelper(mRankingHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001645 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001646 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001647 mListener = mock(ManagedServices.ManagedServiceInfo.class);
1648 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001649 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001650
1651 try {
1652 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1653 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001654 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 }
Julia Reynoldsda781472017-04-12 09:41:16 -04001661
1662 @Test
Julia Reynoldsda781472017-04-12 09:41:16 -04001663 public void testHasCompanionDevice_failure() throws Exception {
1664 when(mCompanionMgr.getAssociations(anyString(), anyInt())).thenThrow(
1665 new IllegalArgumentException());
Julia Reynolds503ed942017-10-04 16:04:56 -04001666 mService.hasCompanionDevice(mListener);
Julia Reynoldsda781472017-04-12 09:41:16 -04001667 }
Julia Reynolds727a7282017-04-13 10:54:01 -04001668
1669 @Test
Julia Reynolds727a7282017-04-13 10:54:01 -04001670 public void testHasCompanionDevice_noService() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001671 mService = new TestableNotificationManagerService(mContext);
Julia Reynolds727a7282017-04-13 10:54:01 -04001672
Julia Reynolds503ed942017-10-04 16:04:56 -04001673 assertFalse(mService.hasCompanionDevice(mListener));
Julia Reynolds727a7282017-04-13 10:54:01 -04001674 }
1675
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001676 @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);
Julia Reynolds503ed942017-10-04 16:04:56 -04001682 mService.addNotification(grouped);
1683 mService.addNotification(nonGrouped);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001684
1685 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001686 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001687 nonGrouped.getKey(), 100, null);
1688 snoozeNotificationRunnable.run();
1689
1690 // only snooze the one notification
1691 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
Julia Reynolds503ed942017-10-04 16:04:56 -04001692 assertTrue(nonGrouped.getStats().hasSnoozed());
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001693 }
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);
Julia Reynolds503ed942017-10-04 16:04:56 -04001703 mService.addNotification(parent);
1704 mService.addNotification(child);
1705 mService.addNotification(child2);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001706
1707 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001708 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001709 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);
Julia Reynolds503ed942017-10-04 16:04:56 -04001724 mService.addNotification(parent);
1725 mService.addNotification(child);
1726 mService.addNotification(child2);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001727
1728 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001729 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001730 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);
Julia Reynolds503ed942017-10-04 16:04:56 -04001744 mService.addNotification(parent);
1745 mService.addNotification(child);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001746
1747 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001748 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001749 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);
Julia Reynolds503ed942017-10-04 16:04:56 -04001760 mService.addNotification(child);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001761
1762 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001763 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001764 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 }
Julia Reynoldsb852e562017-06-06 16:14:18 -04001807
1808 @Test
Julia Reynolds92febc32017-10-26 11:30:31 -04001809 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
Julia Reynoldsb852e562017-06-06 16:14:18 -04001875 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
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001885 verify(mListeners, times(1)).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001886 c.flattenToString(), 0, true, true);
1887 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1888 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001889 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001890 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
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001904 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001905 c.flattenToString(), 0, true, true);
1906 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1907 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001908 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001909 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);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001925 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001926 any(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001927 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001928 any(), anyInt(), anyBoolean(), anyBoolean());
1929 }
Julia Reynolds68263d12017-06-21 14:21:19 -04001930
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
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001937 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001938 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04001939 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001940 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001941 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04001942 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
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001951 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001952 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04001953 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001954 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001955 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04001956 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
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001965 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001966 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04001967 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001968 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(
Julia Reynolds68263d12017-06-21 14:21:19 -04001989 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001990 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04001991 any(), anyInt(), anyBoolean(), anyBoolean());
1992 }
Julia Reynolds8aebf352017-06-26 11:35:33 -04001993
1994 @Test
Julia Reynoldse1816412017-10-24 10:39:11 -04001995 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
Julia Reynolds8aebf352017-06-26 11:35:33 -04002037 public void testOnlyAutogroupIfGroupChanged_noPriorNoti_autogroups() throws Exception {
2038 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002039 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002040 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002041 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002042 runnable.run();
2043 waitForIdle();
2044
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002045 verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002046 }
2047
2048 @Test
2049 public void testOnlyAutogroupIfGroupChanged_groupChanged_autogroups()
2050 throws Exception {
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002051 NotificationRecord r =
2052 generateNotificationRecord(mTestNotificationChannel, 0, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002053 mService.addNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002054
2055 r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002056 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002057 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002058 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002059 runnable.run();
2060 waitForIdle();
2061
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002062 verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002063 }
2064
2065 @Test
2066 public void testOnlyAutogroupIfGroupChanged_noGroupChanged_autogroups()
2067 throws Exception {
Julia Reynolds4db59552017-06-30 13:34:01 -04002068 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group",
2069 false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002070 mService.addNotification(r);
2071 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002072
2073 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002074 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002075 runnable.run();
2076 waitForIdle();
2077
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002078 verify(mGroupHelper, never()).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002079 }
Beverly40239d92017-07-07 10:20:41 -04002080
Julia Reynolds4db59552017-06-30 13:34:01 -04002081 @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);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002090 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
2091 nb.build(), new UserHandle(mUid), null, 0);
Julia Reynolds4db59552017-06-30 13:34:01 -04002092 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
Julia Reynolds503ed942017-10-04 16:04:56 -04002098 NotificationRecord posted = mService.findNotificationLocked(
Julia Reynolds4db59552017-06-30 13:34:01 -04002099 PKG, null, nr.sbn.getId(), nr.sbn.getUserId());
2100
2101 assertFalse(posted.getNotification().isColorized());
2102 }
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002103
2104 @Test
2105 public void testGetNotificationCountLocked() throws Exception {
2106 for (int i = 0; i < 20; i++) {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002107 NotificationRecord r =
2108 generateNotificationRecord(mTestNotificationChannel, i, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002109 mService.addEnqueuedNotification(r);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002110 }
2111 for (int i = 0; i < 20; i++) {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002112 NotificationRecord r =
2113 generateNotificationRecord(mTestNotificationChannel, i, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002114 mService.addNotification(r);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002115 }
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
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002123 StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "tag", mUid, 0,
2124 n, new UserHandle(mUid), null, 0);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002125 NotificationRecord otherPackage =
2126 new NotificationRecord(mContext, sbn, mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002127 mService.addEnqueuedNotification(otherPackage);
2128 mService.addNotification(otherPackage);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002129
2130 // Same notifications are enqueued as posted, everything counts b/c id and tag don't match
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002131 int userId = new UserHandle(mUid).getIdentifier();
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002132 assertEquals(40,
Julia Reynolds503ed942017-10-04 16:04:56 -04002133 mService.getNotificationCountLocked(PKG, userId, 0, null));
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002134 assertEquals(40,
Julia Reynolds503ed942017-10-04 16:04:56 -04002135 mService.getNotificationCountLocked(PKG, userId, 0, "tag2"));
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002136 assertEquals(2,
Julia Reynolds503ed942017-10-04 16:04:56 -04002137 mService.getNotificationCountLocked("a", userId, 0, "banana"));
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002138
2139 // exclude a known notification - it's excluded from only the posted list, not enqueued
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002140 assertEquals(39,
Julia Reynolds503ed942017-10-04 16:04:56 -04002141 mService.getNotificationCountLocked(PKG, userId, 0, "tag"));
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002142 }
2143
2144 @Test
Julia Reynolds51710712017-07-19 13:48:07 -04002145 public void testAddAutogroup_requestsSort() throws Exception {
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002146 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002147 mService.setRankingHandler(rh);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002148
2149 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002150 mService.addNotification(r);
2151 mService.addAutogroupKeyLocked(r.getKey());
Julia Reynolds51710712017-07-19 13:48:07 -04002152
2153 verify(rh, times(1)).requestSort();
2154 }
2155
2156 @Test
2157 public void testRemoveAutogroup_requestsSort() throws Exception {
2158 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002159 mService.setRankingHandler(rh);
Julia Reynolds51710712017-07-19 13:48:07 -04002160
2161 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2162 r.setOverrideGroupKey("TEST");
Julia Reynolds503ed942017-10-04 16:04:56 -04002163 mService.addNotification(r);
2164 mService.removeAutogroupKeyLocked(r.getKey());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002165
Julia Reynolds51710712017-07-19 13:48:07 -04002166 verify(rh, times(1)).requestSort();
2167 }
2168
2169 @Test
2170 public void testReaddAutogroup_noSort() throws Exception {
2171 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002172 mService.setRankingHandler(rh);
Julia Reynolds51710712017-07-19 13:48:07 -04002173
2174 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2175 r.setOverrideGroupKey("TEST");
Julia Reynolds503ed942017-10-04 16:04:56 -04002176 mService.addNotification(r);
2177 mService.addAutogroupKeyLocked(r.getKey());
Julia Reynolds51710712017-07-19 13:48:07 -04002178
2179 verify(rh, never()).requestSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002180 }
2181
2182 @Test
2183 public void testHandleRankingSort_sendsUpdateOnSignalExtractorChange() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04002184 mService.setRankingHelper(mRankingHelper);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002185 NotificationManagerService.WorkerHandler handler = mock(
2186 NotificationManagerService.WorkerHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002187 mService.setHandler(handler);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002188
2189 Map<String, Answer> answers = getSignalExtractorSideEffects();
2190 for (String message : answers.keySet()) {
Julia Reynolds503ed942017-10-04 16:04:56 -04002191 mService.clearNotifications();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002192 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002193 mService.addNotification(r);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002194
2195 doAnswer(answers.get(message)).when(mRankingHelper).extractSignals(r);
2196
Julia Reynolds503ed942017-10-04 16:04:56 -04002197 mService.handleRankingSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002198 }
2199 verify(handler, times(answers.size())).scheduleSendRankingUpdate();
2200 }
2201
2202 @Test
2203 public void testHandleRankingSort_noUpdateWhenNoSignalChange() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04002204 mService.setRankingHelper(mRankingHelper);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002205 NotificationManagerService.WorkerHandler handler = mock(
2206 NotificationManagerService.WorkerHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002207 mService.setHandler(handler);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002208
2209 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002210 mService.addNotification(r);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002211
Julia Reynolds503ed942017-10-04 16:04:56 -04002212 mService.handleRankingSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002213 verify(handler, never()).scheduleSendRankingUpdate();
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002214 }
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002215
2216 @Test
2217 public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception {
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002218 final String upgradeXml = "<notification-policy version=\"1\">"
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002219 + "<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>";
Julia Reynolds503ed942017-10-04 16:04:56 -04002230 mService.readPolicyXml(
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002231 new BufferedInputStream(new ByteArrayInputStream(upgradeXml.getBytes())), false);
Kristian Monsen30f59b22018-04-09 10:27:16 +02002232 verify(mListeners, times(1)).readXml(any(), any());
2233 verify(mConditionProviders, times(1)).readXml(any(), any());
2234 verify(mAssistants, times(1)).readXml(any(), any());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002235
2236 // numbers are inflated for setup
2237 verify(mListeners, times(1)).migrateToXml();
2238 verify(mConditionProviders, times(1)).migrateToXml();
2239 verify(mAssistants, times(1)).migrateToXml();
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002240 verify(mAssistants, times(2)).ensureAssistant();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002241 }
2242
2243 @Test
2244 public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception {
2245 final String preupgradeXml = "<notification-policy version=\"1\">"
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002246 + "<ranking></ranking>"
2247 + "</notification-policy>";
Julia Reynolds503ed942017-10-04 16:04:56 -04002248 mService.readPolicyXml(
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002249 new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
Kristian Monsen30f59b22018-04-09 10:27:16 +02002250 verify(mListeners, never()).readXml(any(), any());
2251 verify(mConditionProviders, never()).readXml(any(), any());
2252 verify(mAssistants, never()).readXml(any(), any());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002253
2254 // numbers are inflated for setup
2255 verify(mListeners, times(2)).migrateToXml();
2256 verify(mConditionProviders, times(2)).migrateToXml();
2257 verify(mAssistants, times(2)).migrateToXml();
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002258 verify(mAssistants, times(2)).ensureAssistant();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002259 }
2260
Beverlyd4f96492017-08-02 13:36:11 -04002261
2262 @Test
2263 public void testLocaleChangedCallsUpdateDefaultZenModeRules() throws Exception {
2264 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002265 mService.mZenModeHelper = mZenModeHelper;
2266 mService.mLocaleChangeReceiver.onReceive(mContext,
Beverlyd4f96492017-08-02 13:36:11 -04002267 new Intent(Intent.ACTION_LOCALE_CHANGED));
2268
2269 verify(mZenModeHelper, times(1)).updateDefaultZenRules();
2270 }
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002271
2272 @Test
2273 public void testBumpFGImportance_noChannelChangePreOApp() throws Exception {
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002274 String preOPkg = PKG_N_MR1;
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002275 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)
Julia Reynoldse5c60452018-04-30 14:41:36 -04002287 .setFlag(FLAG_FOREGROUND_SERVICE, true)
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002288 .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,
Julia Reynolds503ed942017-10-04 16:04:56 -04002297 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002298
2299 nb = new Notification.Builder(mContext)
2300 .setContentTitle("foo")
2301 .setSmallIcon(android.R.drawable.sym_def_app_icon)
Julia Reynoldse5c60452018-04-30 14:41:36 -04002302 .setFlag(FLAG_FOREGROUND_SERVICE, true)
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002303 .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,
Julia Reynolds503ed942017-10-04 16:04:56 -04002312 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002313
2314 NotificationChannel defaultChannel = mBinderService.getNotificationChannel(
2315 preOPkg, NotificationChannel.DEFAULT_CHANNEL_ID);
2316 assertEquals(IMPORTANCE_UNSPECIFIED, defaultChannel.getImportance());
2317 }
Julia Reynolds503ed942017-10-04 16:04:56 -04002318
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
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002329 public void testStats_updatedOnUserExpansion() throws Exception {
2330 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002331 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
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002340 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
Julia Reynolds503ed942017-10-04 16:04:56 -04002351 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
Dieter Hsud39f0d52018-04-14 02:08:30 +08002364 final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 1, 2, true);
Julia Reynolds503ed942017-10-04 16:04:56 -04002365 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
Dieter Hsud39f0d52018-04-14 02:08:30 +08002378 final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
Julia Reynolds503ed942017-10-04 16:04:56 -04002379 mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.sbn.getTag(),
Dieter Hsud39f0d52018-04-14 02:08:30 +08002380 r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD, nv);
Julia Reynolds503ed942017-10-04 16:04:56 -04002381 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 }
Julia Reynolds7bcb57b2018-01-22 10:37:58 -05002405
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 }
Julia Reynoldsd78263d2018-01-30 10:40:41 -05002503
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 }
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002517
2518 @Test
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002519 public void updateUriPermissions_update() throws Exception {
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002520 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, "");
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002524 message1.setData("",
2525 ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1));
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002526 Message message2 = new Message("", 1, "");
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002527 message2.setData("",
2528 ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 2));
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002529
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002530 Notification.Builder nbA = new Notification.Builder(mContext, c.getId())
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002531 .setContentTitle("foo")
2532 .setSmallIcon(android.R.drawable.sym_def_app_icon)
2533 .setStyle(new Notification.MessagingStyle("")
2534 .addMessage(message1)
2535 .addMessage(message2));
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002536 NotificationRecord recordA = new NotificationRecord(mContext, new StatusBarNotification(
2537 PKG, PKG, 0, "tag", mUid, 0, nbA.build(), new UserHandle(mUid), null, 0), c);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002538
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002539 // 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())
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002550 .setContentTitle("foo")
2551 .setSmallIcon(android.R.drawable.sym_def_app_icon)
2552 .setStyle(new Notification.MessagingStyle("").addMessage(message2));
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002553 NotificationRecord recordB = new NotificationRecord(mContext, new StatusBarNotification(PKG,
2554 PKG, 0, "tag", mUid, 0, nbB.build(), new UserHandle(mUid), null, 0), c);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002555
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002556 // Update means we drop access to first
2557 reset(mAm);
2558 mService.updateUriPermissions(recordB, recordA, mContext.getPackageName(),
2559 UserHandle.USER_SYSTEM);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002560 verify(mAm, times(1)).revokeUriPermissionFromOwner(any(), eq(message1.getDataUri()),
2561 anyInt(), anyInt());
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002562
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002563 // 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());
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002569
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002570 // 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),
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002575 anyInt(), anyInt());
2576 }
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05002577
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
Julia Reynoldseac2da22018-04-12 10:48:46 -04002591 | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_LIGHTS
2592 | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05002593 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 }
Julia Reynolds7217dc92018-03-07 12:12:09 -05002698
2699 @Test
Julia Reynoldse5c60452018-04-30 14:41:36 -04002700 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
Julia Reynolds7217dc92018-03-07 12:12:09 -05002720 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
Dan Sandler7d67bd42018-05-15 14:06:38 -04002739 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
Julia Reynolds7217dc92018-03-07 12:12:09 -05002789 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
Dan Sandler7d67bd42018-05-15 14:06:38 -04002808 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
Julia Reynolds7217dc92018-03-07 12:12:09 -05002865 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 }
Beverly5a20a5e2018-03-06 15:02:44 -05002901
2902 @Test
Dan Sandler7d67bd42018-05-15 14:06:38 -04002903 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
Julia Reynoldsa4fb9da2018-06-04 12:27:58 -04002922 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
Julia Reynolds6b302d02018-06-19 15:39:23 -04002945 public void testVisualDifference_summaryNewNotification() {
2946 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2947 .setGroup("bananas")
2948 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
2949 .setContentText("bar");
2950 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2951 nb2.build(), new UserHandle(mUid), null, 0);
2952 NotificationRecord r2 =
2953 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2954
2955 assertFalse(mService.isVisuallyInterruptive(null, r2));
2956 }
2957
2958 @Test
Beverly5a20a5e2018-03-06 15:02:44 -05002959 public void testHideAndUnhideNotificationsOnSuspendedPackageBroadcast() {
2960 // post 2 notification from this package
2961 final NotificationRecord notif1 = generateNotificationRecord(
2962 mTestNotificationChannel, 1, null, true);
2963 final NotificationRecord notif2 = generateNotificationRecord(
2964 mTestNotificationChannel, 2, null, false);
2965 mService.addNotification(notif1);
2966 mService.addNotification(notif2);
2967
2968 // on broadcast, hide the 2 notifications
2969 mService.simulatePackageSuspendBroadcast(true, PKG);
2970 ArgumentCaptor<List> captorHide = ArgumentCaptor.forClass(List.class);
2971 verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
2972 assertEquals(2, captorHide.getValue().size());
2973
2974 // on broadcast, unhide the 2 notifications
2975 mService.simulatePackageSuspendBroadcast(false, PKG);
2976 ArgumentCaptor<List> captorUnhide = ArgumentCaptor.forClass(List.class);
2977 verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
2978 assertEquals(2, captorUnhide.getValue().size());
2979 }
2980
2981 @Test
2982 public void testNoNotificationsHiddenOnSuspendedPackageBroadcast() {
2983 // post 2 notification from this package
2984 final NotificationRecord notif1 = generateNotificationRecord(
2985 mTestNotificationChannel, 1, null, true);
2986 final NotificationRecord notif2 = generateNotificationRecord(
2987 mTestNotificationChannel, 2, null, false);
2988 mService.addNotification(notif1);
2989 mService.addNotification(notif2);
2990
2991 // on broadcast, nothing is hidden since no notifications are of package "test_package"
2992 mService.simulatePackageSuspendBroadcast(true, "test_package");
2993 ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
2994 verify(mListeners, times(1)).notifyHiddenLocked(captor.capture());
2995 assertEquals(0, captor.getValue().size());
2996 }
Kristian Monsen30f59b22018-04-09 10:27:16 +02002997
2998 @Test
2999 public void testCanUseManagedServicesLowRamNoWatchNullPkg() {
3000 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3001 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3002 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3003 .thenReturn(new String[] {"a", "b", "c"});
3004 when(mContext.getResources()).thenReturn(mResources);
3005
3006 assertEquals(false, mService.canUseManagedServices(null));
3007 }
3008
3009 @Test
3010 public void testCanUseManagedServicesLowRamNoWatchValidPkg() {
3011 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3012 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3013 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3014 .thenReturn(new String[] {"a", "b", "c"});
3015 when(mContext.getResources()).thenReturn(mResources);
3016
3017 assertEquals(true, mService.canUseManagedServices("b"));
3018 }
3019
3020 @Test
3021 public void testCanUseManagedServicesLowRamNoWatchNoValidPkg() {
3022 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3023 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3024 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3025 .thenReturn(new String[] {"a", "b", "c"});
3026 when(mContext.getResources()).thenReturn(mResources);
3027
3028 assertEquals(false, mService.canUseManagedServices("d"));
3029 }
3030
3031 @Test
3032 public void testCanUseManagedServicesLowRamWatchNoValidPkg() {
3033 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
3034 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3035 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3036 .thenReturn(new String[] {"a", "b", "c"});
3037 when(mContext.getResources()).thenReturn(mResources);
3038
3039 assertEquals(true, mService.canUseManagedServices("d"));
3040 }
3041
3042 @Test
3043 public void testCanUseManagedServicesNoLowRamNoWatchValidPkg() {
3044 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3045 when(mActivityManager.isLowRamDevice()).thenReturn(false);
3046 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3047 .thenReturn(new String[] {"a", "b", "c"});
3048 when(mContext.getResources()).thenReturn(mResources);
3049
3050 assertEquals(true, mService.canUseManagedServices("d"));
3051 }
3052
3053 @Test
3054 public void testCanUseManagedServicesNoLowRamWatchValidPkg() {
3055 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
3056 when(mActivityManager.isLowRamDevice()).thenReturn(false);
3057 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3058 .thenReturn(new String[] {"a", "b", "c"});
3059 when(mContext.getResources()).thenReturn(mResources);
3060
3061 assertEquals(true, mService.canUseManagedServices("d"));
3062 }
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -04003063
3064 @Test
3065 public void testOnNotificationVisibilityChanged_triggersInterruptionUsageStat() {
3066 final NotificationRecord r = generateNotificationRecord(
3067 mTestNotificationChannel, 1, null, true);
3068 r.setTextChanged(true);
3069 mService.addNotification(r);
3070
3071 mService.mNotificationDelegate.onNotificationVisibilityChanged(new NotificationVisibility[]
3072 {NotificationVisibility.obtain(r.getKey(), 1, 1, true)},
3073 new NotificationVisibility[]{});
3074
3075 verify(mAppUsageStats).reportInterruptiveNotification(anyString(), anyString(), anyInt());
3076 }
3077
3078 @Test
3079 public void testSetNotificationsShownFromListener_triggersInterruptionUsageStat()
3080 throws RemoteException {
3081 final NotificationRecord r = generateNotificationRecord(
3082 mTestNotificationChannel, 1, null, true);
3083 r.setTextChanged(true);
3084 mService.addNotification(r);
3085
3086 mBinderService.setNotificationsShownFromListener(null, new String[] {r.getKey()});
3087
3088 verify(mAppUsageStats).reportInterruptiveNotification(anyString(), anyString(), anyInt());
3089 }
3090
3091 @Test
3092 public void testMybeRecordInterruptionLocked_doesNotRecordTwice()
3093 throws RemoteException {
3094 final NotificationRecord r = generateNotificationRecord(
3095 mTestNotificationChannel, 1, null, true);
3096 r.setInterruptive(true);
3097 mService.addNotification(r);
3098
3099 mService.maybeRecordInterruptionLocked(r);
3100 mService.maybeRecordInterruptionLocked(r);
3101
3102 verify(mAppUsageStats, times(1)).reportInterruptiveNotification(
3103 anyString(), anyString(), anyInt());
3104 }
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -05003105}