blob: 955e2477fc660aa407f719516d3e4d66942a039b [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);
Beverlyc7858552018-09-14 09:49:07 -0400503
504 // isBlocked is only used for user blocking, not app suspension
505 assertFalse(mService.isBlocked(r, mUsageStats));
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500506 }
507
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500508 @Test
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500509 public void testBlockedNotifications_blockedChannel() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500510 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
511
512 NotificationChannel channel = new NotificationChannel("id", "name",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400513 NotificationManager.IMPORTANCE_NONE);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500514 NotificationRecord r = generateNotificationRecord(channel);
Julia Reynolds503ed942017-10-04 16:04:56 -0400515 assertTrue(mService.isBlocked(r, mUsageStats));
Geoffrey Pitschd5bcf212017-06-01 15:45:35 -0400516 verify(mUsageStats, times(1)).registerBlocked(eq(r));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400517
518 mBinderService.createNotificationChannels(
519 PKG, new ParceledListSlice(Arrays.asList(channel)));
520 final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
521 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
522 sbn.getId(), sbn.getNotification(), sbn.getUserId());
523 waitForIdle();
524 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
525 }
526
527 @Test
528 public void testEnqueuedBlockedNotifications_appBlockedChannelForegroundService()
529 throws Exception {
530 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
531
532 NotificationChannel channel = new NotificationChannel("blocked", "name",
533 NotificationManager.IMPORTANCE_NONE);
534 mBinderService.createNotificationChannels(
535 PKG, new ParceledListSlice(Arrays.asList(channel)));
536
537 final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400538 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400539 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
540 sbn.getId(), sbn.getNotification(), sbn.getUserId());
541 waitForIdle();
542 assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
543 assertEquals(IMPORTANCE_LOW,
Julia Reynolds503ed942017-10-04 16:04:56 -0400544 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400545 assertEquals(IMPORTANCE_LOW,
546 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
547 }
548
549 @Test
550 public void testEnqueuedBlockedNotifications_userBlockedChannelForegroundService()
551 throws Exception {
552 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
553
554 NotificationChannel channel =
555 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_HIGH);
556 mBinderService.createNotificationChannels(
557 PKG, new ParceledListSlice(Arrays.asList(channel)));
558
559 NotificationChannel update =
560 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
561 mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
562 waitForIdle();
563 assertEquals(IMPORTANCE_NONE,
564 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
565
Dianne Hackborn025d4a52018-04-30 16:23:26 -0700566 StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400567 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400568 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
569 sbn.getId(), sbn.getNotification(), sbn.getUserId());
570 waitForIdle();
Dianne Hackborn025d4a52018-04-30 16:23:26 -0700571 // The first time a foreground service notification is shown, we allow the channel
572 // to be updated to allow it to be seen.
573 assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
574 assertEquals(IMPORTANCE_LOW,
575 mService.getNotificationRecord(sbn.getKey()).getImportance());
576 assertEquals(IMPORTANCE_LOW,
577 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
578 mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
579 waitForIdle();
580
581 update = new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
582 update.setFgServiceShown(true);
583 mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
584 waitForIdle();
585 assertEquals(IMPORTANCE_NONE,
586 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
587
588 sbn = generateNotificationRecord(channel).sbn;
589 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
590 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
591 sbn.getId(), sbn.getNotification(), sbn.getUserId());
592 waitForIdle();
593 // The second time it is shown, we keep the user's preference.
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400594 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400595 assertNull(mService.getNotificationRecord(sbn.getKey()));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400596 assertEquals(IMPORTANCE_NONE,
597 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500598 }
599
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500600 @Test
Julia Reynolds005c8b92017-08-24 10:35:53 -0400601 public void testBlockedNotifications_blockedChannelGroup() throws Exception {
602 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
Julia Reynolds503ed942017-10-04 16:04:56 -0400603 mService.setRankingHelper(mRankingHelper);
Julia Reynolds005c8b92017-08-24 10:35:53 -0400604 when(mRankingHelper.isGroupBlocked(anyString(), anyInt(), anyString())).thenReturn(true);
605
606 NotificationChannel channel = new NotificationChannel("id", "name",
607 NotificationManager.IMPORTANCE_HIGH);
608 channel.setGroup("something");
609 NotificationRecord r = generateNotificationRecord(channel);
Julia Reynolds503ed942017-10-04 16:04:56 -0400610 assertTrue(mService.isBlocked(r, mUsageStats));
Julia Reynolds005c8b92017-08-24 10:35:53 -0400611 verify(mUsageStats, times(1)).registerBlocked(eq(r));
612 }
613
614 @Test
Julia Reynolds4da79702017-06-01 11:06:10 -0400615 public void testEnqueuedBlockedNotifications_blockedApp() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500616 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
617
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400618 mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
Julia Reynolds4da79702017-06-01 11:06:10 -0400619
620 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
621 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
622 sbn.getId(), sbn.getNotification(), sbn.getUserId());
623 waitForIdle();
624 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500625 }
626
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500627 @Test
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400628 public void testEnqueuedBlockedNotifications_blockedAppForegroundService() throws Exception {
629 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
630
631 mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
632
633 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400634 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400635 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
636 sbn.getId(), sbn.getNotification(), sbn.getUserId());
637 waitForIdle();
638 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400639 assertNull(mService.getNotificationRecord(sbn.getKey()));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400640 }
641
642 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500643 public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500644 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400645 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500646 waitForIdle();
Julia Reynolds080361e2017-07-13 11:23:12 -0400647 StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500648 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400649 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500650 }
651
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500652 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500653 public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500654 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400655 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500656 mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500657 waitForIdle();
658 StatusBarNotification[] notifs =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500659 mBinderService.getActiveNotifications(PKG);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500660 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400661 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500662 }
663
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500664 @Test
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500665 public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500666 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400667 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500668 waitForIdle();
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500669 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400670 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500671 mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500672 waitForIdle();
673 StatusBarNotification[] notifs =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500674 mBinderService.getActiveNotifications(PKG);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500675 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400676 assertEquals(0, mService.getNotificationRecordCount());
677 ArgumentCaptor<NotificationStats> captor = ArgumentCaptor.forClass(NotificationStats.class);
678 verify(mListeners, times(1)).notifyRemovedLocked(any(), anyInt(), captor.capture());
679 assertEquals(NotificationStats.DISMISSAL_OTHER, captor.getValue().getDismissalSurface());
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500680 }
681
682 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500683 public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -0400684 NotificationRecord r = generateNotificationRecord(null);
685 final StatusBarNotification sbn = r.sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500686 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400687 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500688 mBinderService.cancelNotificationsFromListener(null, null);
689 waitForIdle();
690 StatusBarNotification[] notifs =
691 mBinderService.getActiveNotifications(sbn.getPackageName());
692 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400693 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500694 }
695
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500696 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500697 public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
698 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500699 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400700 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500701 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500702 waitForIdle();
703 StatusBarNotification[] notifs =
704 mBinderService.getActiveNotifications(sbn.getPackageName());
705 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400706 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds080361e2017-07-13 11:23:12 -0400707 }
708
709 @Test
710 public void testUserInitiatedClearAll_noLeak() throws Exception {
711 final NotificationRecord n = generateNotificationRecord(
712 mTestNotificationChannel, 1, "group", true);
713
714 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
715 n.sbn.getId(), n.sbn.getNotification(), n.sbn.getUserId());
716 waitForIdle();
717
Julia Reynolds503ed942017-10-04 16:04:56 -0400718 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Julia Reynolds080361e2017-07-13 11:23:12 -0400719 n.getUserId());
720 waitForIdle();
721 StatusBarNotification[] notifs =
722 mBinderService.getActiveNotifications(n.sbn.getPackageName());
723 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400724 assertEquals(0, mService.getNotificationRecordCount());
725 ArgumentCaptor<NotificationStats> captor = ArgumentCaptor.forClass(NotificationStats.class);
726 verify(mListeners, times(1)).notifyRemovedLocked(any(), anyInt(), captor.capture());
727 assertEquals(NotificationStats.DISMISSAL_OTHER, captor.getValue().getDismissalSurface());
Julia Reynolds080361e2017-07-13 11:23:12 -0400728 }
729
730 @Test
731 public void testCancelAllNotificationsCancelsChildren() throws Exception {
732 final NotificationRecord parent = generateNotificationRecord(
733 mTestNotificationChannel, 1, "group1", true);
734 final NotificationRecord child = generateNotificationRecord(
735 mTestNotificationChannel, 2, "group1", false);
736
737 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
738 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
739 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
740 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
741 waitForIdle();
742
743 mBinderService.cancelAllNotifications(PKG, parent.sbn.getUserId());
744 waitForIdle();
Julia Reynolds503ed942017-10-04 16:04:56 -0400745 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500746 }
747
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500748 @Test
Julia Reynolds0839c022017-06-15 15:24:01 -0400749 public void testCancelAllNotificationsMultipleEnqueuedDoesNotCrash() throws Exception {
750 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
751 for (int i = 0; i < 10; i++) {
752 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
753 sbn.getId(), sbn.getNotification(), sbn.getUserId());
754 }
755 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
756 waitForIdle();
Julia Reynolds080361e2017-07-13 11:23:12 -0400757
Julia Reynolds503ed942017-10-04 16:04:56 -0400758 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds0839c022017-06-15 15:24:01 -0400759 }
760
761 @Test
762 public void testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash() throws Exception {
763 final NotificationRecord parent = generateNotificationRecord(
764 mTestNotificationChannel, 1, "group1", true);
765 final NotificationRecord parentAsChild = generateNotificationRecord(
766 mTestNotificationChannel, 1, "group1", false);
767 final NotificationRecord child = generateNotificationRecord(
768 mTestNotificationChannel, 2, "group1", false);
769
770 // fully post parent notification
771 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
772 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
773 waitForIdle();
774
775 // enqueue the child several times
776 for (int i = 0; i < 10; i++) {
777 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
778 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
779 }
780 // make the parent a child, which will cancel the child notification
781 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
782 parentAsChild.sbn.getId(), parentAsChild.sbn.getNotification(),
783 parentAsChild.sbn.getUserId());
784 waitForIdle();
Julia Reynolds080361e2017-07-13 11:23:12 -0400785
Julia Reynolds503ed942017-10-04 16:04:56 -0400786 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds0839c022017-06-15 15:24:01 -0400787 }
788
789 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500790 public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
791 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400792 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500793 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400794 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500795 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500796 waitForIdle();
797 StatusBarNotification[] notifs =
798 mBinderService.getActiveNotifications(sbn.getPackageName());
799 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400800 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500801 }
802
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500803 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500804 public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
805 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400806 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500807 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400808 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500809 mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
810 waitForIdle();
811 StatusBarNotification[] notifs =
812 mBinderService.getActiveNotifications(sbn.getPackageName());
813 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400814 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500815 }
816
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500817 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500818 public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
819 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500820 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400821 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500822 mBinderService.cancelAllNotifications(null, sbn.getUserId());
823 waitForIdle();
824 StatusBarNotification[] notifs =
825 mBinderService.getActiveNotifications(sbn.getPackageName());
826 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400827 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500828 }
829
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500830 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500831 public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
832 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500833 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400834 sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500835 // Null pkg is how we signal a user switch.
836 mBinderService.cancelAllNotifications(null, sbn.getUserId());
837 waitForIdle();
838 StatusBarNotification[] notifs =
839 mBinderService.getActiveNotifications(sbn.getPackageName());
840 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400841 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500842 }
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500843
844 @Test
Beverly40239d92017-07-07 10:20:41 -0400845 public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception {
846 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
847 sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR;
848 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
849 sbn.getId(), sbn.getNotification(), sbn.getUserId());
850 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
851 waitForIdle();
852 StatusBarNotification[] notifs =
853 mBinderService.getActiveNotifications(sbn.getPackageName());
854 assertEquals(0, notifs.length);
855 }
856
857 @Test
858 public void testCancelAllNotifications_CancelsNoClearFlag() throws Exception {
859 final NotificationRecord notif = generateNotificationRecord(
860 mTestNotificationChannel, 1, "group", true);
861 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
Julia Reynolds503ed942017-10-04 16:04:56 -0400862 mService.addNotification(notif);
863 mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true,
Beverly40239d92017-07-07 10:20:41 -0400864 notif.getUserId(), 0, null);
865 waitForIdle();
866 StatusBarNotification[] notifs =
867 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
868 assertEquals(0, notifs.length);
869 }
870
871 @Test
872 public void testUserInitiatedCancelAllOnClearAll_NoClearFlag() throws Exception {
873 final NotificationRecord notif = generateNotificationRecord(
874 mTestNotificationChannel, 1, "group", true);
875 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
Julia Reynolds503ed942017-10-04 16:04:56 -0400876 mService.addNotification(notif);
Beverly40239d92017-07-07 10:20:41 -0400877
Julia Reynolds503ed942017-10-04 16:04:56 -0400878 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Beverly40239d92017-07-07 10:20:41 -0400879 notif.getUserId());
880 waitForIdle();
881 StatusBarNotification[] notifs =
882 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
883 assertEquals(1, notifs.length);
884 }
885
886 @Test
887 public void testCancelAllCancelNotificationsFromListener_NoClearFlag() throws Exception {
888 final NotificationRecord parent = generateNotificationRecord(
889 mTestNotificationChannel, 1, "group", true);
890 final NotificationRecord child = generateNotificationRecord(
891 mTestNotificationChannel, 2, "group", false);
892 final NotificationRecord child2 = generateNotificationRecord(
893 mTestNotificationChannel, 3, "group", false);
894 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
895 final NotificationRecord newGroup = generateNotificationRecord(
896 mTestNotificationChannel, 4, "group2", false);
Julia Reynolds503ed942017-10-04 16:04:56 -0400897 mService.addNotification(parent);
898 mService.addNotification(child);
899 mService.addNotification(child2);
900 mService.addNotification(newGroup);
901 mService.getBinderService().cancelNotificationsFromListener(null, null);
Beverly40239d92017-07-07 10:20:41 -0400902 waitForIdle();
903 StatusBarNotification[] notifs =
904 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
905 assertEquals(1, notifs.length);
906 }
907
908 @Test
909 public void testUserInitiatedCancelAllWithGroup_NoClearFlag() throws Exception {
910 final NotificationRecord parent = generateNotificationRecord(
911 mTestNotificationChannel, 1, "group", true);
912 final NotificationRecord child = generateNotificationRecord(
913 mTestNotificationChannel, 2, "group", false);
914 final NotificationRecord child2 = generateNotificationRecord(
915 mTestNotificationChannel, 3, "group", false);
916 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
917 final NotificationRecord newGroup = generateNotificationRecord(
918 mTestNotificationChannel, 4, "group2", false);
Julia Reynolds503ed942017-10-04 16:04:56 -0400919 mService.addNotification(parent);
920 mService.addNotification(child);
921 mService.addNotification(child2);
922 mService.addNotification(newGroup);
923 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Beverly40239d92017-07-07 10:20:41 -0400924 parent.getUserId());
925 waitForIdle();
926 StatusBarNotification[] notifs =
927 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
928 assertEquals(1, notifs.length);
929 }
930
931 @Test
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400932 public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
933 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400934 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400935 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400936 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400937 mInternalService.removeForegroundServiceFlagFromNotification(PKG, sbn.getId(),
938 sbn.getUserId());
939 waitForIdle();
940 StatusBarNotification[] notifs =
941 mBinderService.getActiveNotifications(sbn.getPackageName());
Julia Reynoldse5c60452018-04-30 14:41:36 -0400942 assertEquals(0, notifs[0].getNotification().flags & FLAG_FOREGROUND_SERVICE);
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400943 }
944
945 @Test
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400946 public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception {
947 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
948 sbn.getNotification().flags =
Julia Reynoldse5c60452018-04-30 14:41:36 -0400949 Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400950 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
951 sbn.getId(), sbn.getNotification(), sbn.getUserId());
952 sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
953 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
954 sbn.getId(), sbn.getNotification(), sbn.getUserId());
955 mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
956 waitForIdle();
957 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400958 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400959 }
960
961 @Test
Julia Reynolds40f00d72017-12-12 10:47:32 -0500962 public void testCancelAllCancelNotificationsFromListener_ForegroundServiceFlag()
963 throws Exception {
964 final NotificationRecord parent = generateNotificationRecord(
965 mTestNotificationChannel, 1, "group", true);
966 final NotificationRecord child = generateNotificationRecord(
967 mTestNotificationChannel, 2, "group", false);
968 final NotificationRecord child2 = generateNotificationRecord(
969 mTestNotificationChannel, 3, "group", false);
Julia Reynoldse5c60452018-04-30 14:41:36 -0400970 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -0500971 final NotificationRecord newGroup = generateNotificationRecord(
972 mTestNotificationChannel, 4, "group2", false);
973 mService.addNotification(parent);
974 mService.addNotification(child);
975 mService.addNotification(child2);
976 mService.addNotification(newGroup);
977 mService.getBinderService().cancelNotificationsFromListener(null, null);
978 waitForIdle();
979 StatusBarNotification[] notifs =
980 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
981 assertEquals(0, notifs.length);
982 }
983
984 @Test
985 public void testCancelAllCancelNotificationsFromListener_ForegroundServiceFlagWithParameter()
986 throws Exception {
987 final NotificationRecord parent = generateNotificationRecord(
988 mTestNotificationChannel, 1, "group", true);
989 final NotificationRecord child = generateNotificationRecord(
990 mTestNotificationChannel, 2, "group", false);
991 final NotificationRecord child2 = generateNotificationRecord(
992 mTestNotificationChannel, 3, "group", false);
Julia Reynoldse5c60452018-04-30 14:41:36 -0400993 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -0500994 final NotificationRecord newGroup = generateNotificationRecord(
995 mTestNotificationChannel, 4, "group2", false);
996 mService.addNotification(parent);
997 mService.addNotification(child);
998 mService.addNotification(child2);
999 mService.addNotification(newGroup);
1000 String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
1001 child2.sbn.getKey(), newGroup.sbn.getKey()};
1002 mService.getBinderService().cancelNotificationsFromListener(null, keys);
1003 waitForIdle();
1004 StatusBarNotification[] notifs =
1005 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1006 assertEquals(1, notifs.length);
1007 }
1008
1009 @Test
1010 public void testUserInitiatedCancelAllWithGroup_ForegroundServiceFlag() throws Exception {
1011 final NotificationRecord parent = generateNotificationRecord(
1012 mTestNotificationChannel, 1, "group", true);
1013 final NotificationRecord child = generateNotificationRecord(
1014 mTestNotificationChannel, 2, "group", false);
1015 final NotificationRecord child2 = generateNotificationRecord(
1016 mTestNotificationChannel, 3, "group", false);
Julia Reynoldse5c60452018-04-30 14:41:36 -04001017 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -05001018 final NotificationRecord newGroup = generateNotificationRecord(
1019 mTestNotificationChannel, 4, "group2", false);
1020 mService.addNotification(parent);
1021 mService.addNotification(child);
1022 mService.addNotification(child2);
1023 mService.addNotification(newGroup);
1024 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
1025 parent.getUserId());
1026 waitForIdle();
1027 StatusBarNotification[] notifs =
1028 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1029 assertEquals(0, notifs.length);
1030 }
1031
1032 @Test
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001033 public void testFindGroupNotificationsLocked() throws Exception {
1034 // make sure the same notification can be found in both lists and returned
1035 final NotificationRecord group1 = generateNotificationRecord(
1036 mTestNotificationChannel, 1, "group1", true);
Julia Reynolds503ed942017-10-04 16:04:56 -04001037 mService.addEnqueuedNotification(group1);
1038 mService.addNotification(group1);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001039
1040 // should not be returned
1041 final NotificationRecord group2 = generateNotificationRecord(
1042 mTestNotificationChannel, 2, "group2", true);
1043 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
1044 group2.sbn.getId(), group2.sbn.getNotification(), group2.sbn.getUserId());
1045 waitForIdle();
1046
1047 // should not be returned
1048 final NotificationRecord nonGroup = generateNotificationRecord(
1049 mTestNotificationChannel, 3, null, false);
1050 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
1051 nonGroup.sbn.getId(), nonGroup.sbn.getNotification(), nonGroup.sbn.getUserId());
1052 waitForIdle();
1053
1054 // same group, child, should be returned
1055 final NotificationRecord group1Child = generateNotificationRecord(
1056 mTestNotificationChannel, 4, "group1", false);
1057 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, group1Child.sbn.getId(),
1058 group1Child.sbn.getNotification(), group1Child.sbn.getUserId());
1059 waitForIdle();
1060
1061 List<NotificationRecord> inGroup1 =
Julia Reynolds503ed942017-10-04 16:04:56 -04001062 mService.findGroupNotificationsLocked(PKG, group1.getGroupKey(),
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001063 group1.sbn.getUserId());
1064 assertEquals(3, inGroup1.size());
1065 for (NotificationRecord record : inGroup1) {
1066 assertTrue(record.getGroupKey().equals(group1.getGroupKey()));
1067 assertTrue(record.sbn.getId() == 1 || record.sbn.getId() == 4);
1068 }
1069 }
1070
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001071 @Test
Julia Reynolds40f00d72017-12-12 10:47:32 -05001072 public void testCancelAllNotifications_CancelsNoClearFlagOnGoing() throws Exception {
1073 final NotificationRecord notif = generateNotificationRecord(
1074 mTestNotificationChannel, 1, "group", true);
1075 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
1076 mService.addNotification(notif);
1077 mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0,
1078 Notification.FLAG_ONGOING_EVENT, true, notif.getUserId(), 0, null);
1079 waitForIdle();
1080 StatusBarNotification[] notifs =
1081 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1082 assertEquals(0, notifs.length);
1083 }
1084
1085 @Test
1086 public void testCancelAllCancelNotificationsFromListener_NoClearFlagWithParameter()
1087 throws Exception {
1088 final NotificationRecord parent = generateNotificationRecord(
1089 mTestNotificationChannel, 1, "group", true);
1090 final NotificationRecord child = generateNotificationRecord(
1091 mTestNotificationChannel, 2, "group", false);
1092 final NotificationRecord child2 = generateNotificationRecord(
1093 mTestNotificationChannel, 3, "group", false);
1094 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
1095 final NotificationRecord newGroup = generateNotificationRecord(
1096 mTestNotificationChannel, 4, "group2", false);
1097 mService.addNotification(parent);
1098 mService.addNotification(child);
1099 mService.addNotification(child2);
1100 mService.addNotification(newGroup);
1101 String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
1102 child2.sbn.getKey(), newGroup.sbn.getKey()};
1103 mService.getBinderService().cancelNotificationsFromListener(null, keys);
1104 waitForIdle();
1105 StatusBarNotification[] notifs =
1106 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1107 assertEquals(0, notifs.length);
1108 }
1109
1110 @Test
1111 public void testAppInitiatedCancelAllNotifications_CancelsOnGoingFlag() throws Exception {
1112 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
1113 sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1114 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
1115 sbn.getId(), sbn.getNotification(), sbn.getUserId());
1116 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
1117 waitForIdle();
1118 StatusBarNotification[] notifs =
1119 mBinderService.getActiveNotifications(sbn.getPackageName());
1120 assertEquals(0, notifs.length);
1121 }
1122
1123 @Test
1124 public void testCancelAllNotifications_CancelsOnGoingFlag() throws Exception {
1125 final NotificationRecord notif = generateNotificationRecord(
1126 mTestNotificationChannel, 1, "group", true);
1127 notif.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1128 mService.addNotification(notif);
1129 mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true,
1130 notif.getUserId(), 0, null);
1131 waitForIdle();
1132 StatusBarNotification[] notifs =
1133 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1134 assertEquals(0, notifs.length);
1135 }
1136
1137 @Test
1138 public void testUserInitiatedCancelAllOnClearAll_OnGoingFlag() throws Exception {
1139 final NotificationRecord notif = generateNotificationRecord(
1140 mTestNotificationChannel, 1, "group", true);
1141 notif.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1142 mService.addNotification(notif);
1143
1144 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
1145 notif.getUserId());
1146 waitForIdle();
1147 StatusBarNotification[] notifs =
1148 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1149 assertEquals(1, notifs.length);
1150 }
1151
1152 @Test
1153 public void testCancelAllCancelNotificationsFromListener_OnGoingFlag() throws Exception {
1154 final NotificationRecord parent = generateNotificationRecord(
1155 mTestNotificationChannel, 1, "group", true);
1156 final NotificationRecord child = generateNotificationRecord(
1157 mTestNotificationChannel, 2, "group", false);
1158 final NotificationRecord child2 = generateNotificationRecord(
1159 mTestNotificationChannel, 3, "group", false);
1160 child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1161 final NotificationRecord newGroup = generateNotificationRecord(
1162 mTestNotificationChannel, 4, "group2", false);
1163 mService.addNotification(parent);
1164 mService.addNotification(child);
1165 mService.addNotification(child2);
1166 mService.addNotification(newGroup);
1167 mService.getBinderService().cancelNotificationsFromListener(null, null);
1168 waitForIdle();
1169 StatusBarNotification[] notifs =
1170 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1171 assertEquals(1, notifs.length);
1172 }
1173
1174 @Test
1175 public void testCancelAllCancelNotificationsFromListener_OnGoingFlagWithParameter()
1176 throws Exception {
1177 final NotificationRecord parent = generateNotificationRecord(
1178 mTestNotificationChannel, 1, "group", true);
1179 final NotificationRecord child = generateNotificationRecord(
1180 mTestNotificationChannel, 2, "group", false);
1181 final NotificationRecord child2 = generateNotificationRecord(
1182 mTestNotificationChannel, 3, "group", false);
1183 child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1184 final NotificationRecord newGroup = generateNotificationRecord(
1185 mTestNotificationChannel, 4, "group2", false);
1186 mService.addNotification(parent);
1187 mService.addNotification(child);
1188 mService.addNotification(child2);
1189 mService.addNotification(newGroup);
1190 String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
1191 child2.sbn.getKey(), newGroup.sbn.getKey()};
1192 mService.getBinderService().cancelNotificationsFromListener(null, keys);
1193 waitForIdle();
1194 StatusBarNotification[] notifs =
1195 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1196 assertEquals(0, notifs.length);
1197 }
1198
1199 @Test
1200 public void testUserInitiatedCancelAllWithGroup_OnGoingFlag() throws Exception {
1201 final NotificationRecord parent = generateNotificationRecord(
1202 mTestNotificationChannel, 1, "group", true);
1203 final NotificationRecord child = generateNotificationRecord(
1204 mTestNotificationChannel, 2, "group", false);
1205 final NotificationRecord child2 = generateNotificationRecord(
1206 mTestNotificationChannel, 3, "group", false);
1207 child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1208 final NotificationRecord newGroup = generateNotificationRecord(
1209 mTestNotificationChannel, 4, "group2", false);
1210 mService.addNotification(parent);
1211 mService.addNotification(child);
1212 mService.addNotification(child2);
1213 mService.addNotification(newGroup);
1214 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
1215 parent.getUserId());
1216 waitForIdle();
1217 StatusBarNotification[] notifs =
1218 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1219 assertEquals(1, notifs.length);
1220 }
1221
1222 @Test
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001223 public void testTvExtenderChannelOverride_onTv() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001224 mService.setIsTelevision(true);
1225 mService.setRankingHelper(mRankingHelper);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001226 when(mRankingHelper.getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001227 anyString(), anyInt(), eq("foo"), anyBoolean())).thenReturn(
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001228 new NotificationChannel("foo", "foo", IMPORTANCE_HIGH));
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001229
Julia Reynoldsbad42972017-04-25 13:52:49 -04001230 Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001231 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -04001232 generateNotificationRecord(null, tv).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001233 verify(mRankingHelper, times(1)).getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001234 anyString(), anyInt(), eq("foo"), anyBoolean());
1235 }
1236
1237 @Test
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001238 public void testTvExtenderChannelOverride_notOnTv() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001239 mService.setIsTelevision(false);
1240 mService.setRankingHelper(mRankingHelper);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001241 when(mRankingHelper.getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001242 anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001243 mTestNotificationChannel);
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001244
Julia Reynoldsbad42972017-04-25 13:52:49 -04001245 Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001246 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -04001247 generateNotificationRecord(null, tv).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001248 verify(mRankingHelper, times(1)).getNotificationChannel(
1249 anyString(), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean());
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001250 }
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001251
1252 @Test
Julia Reynoldsfc9767b2018-01-22 17:45:16 -05001253 public void testUpdateAppNotifyCreatorBlock() throws Exception {
1254 mService.setRankingHelper(mRankingHelper);
1255
1256 mBinderService.setNotificationsEnabledForPackage(PKG, 0, false);
1257 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1258 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1259
1260 assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
1261 captor.getValue().getAction());
1262 assertEquals(PKG, captor.getValue().getPackage());
1263 assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1264 }
1265
1266 @Test
1267 public void testUpdateAppNotifyCreatorUnblock() throws Exception {
1268 mService.setRankingHelper(mRankingHelper);
1269
1270 mBinderService.setNotificationsEnabledForPackage(PKG, 0, true);
1271 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1272 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1273
1274 assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
1275 captor.getValue().getAction());
1276 assertEquals(PKG, captor.getValue().getPackage());
1277 assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
1278 }
1279
1280 @Test
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001281 public void testUpdateChannelNotifyCreatorBlock() throws Exception {
1282 mService.setRankingHelper(mRankingHelper);
1283 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1284 eq(mTestNotificationChannel.getId()), anyBoolean()))
1285 .thenReturn(mTestNotificationChannel);
1286
1287 NotificationChannel updatedChannel =
1288 new NotificationChannel(mTestNotificationChannel.getId(),
1289 mTestNotificationChannel.getName(), IMPORTANCE_NONE);
1290
1291 mBinderService.updateNotificationChannelForPackage(PKG, 0, updatedChannel);
1292 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1293 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1294
1295 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED,
1296 captor.getValue().getAction());
1297 assertEquals(PKG, captor.getValue().getPackage());
1298 assertEquals(mTestNotificationChannel.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001299 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001300 assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1301 }
1302
1303 @Test
1304 public void testUpdateChannelNotifyCreatorUnblock() throws Exception {
1305 NotificationChannel existingChannel =
1306 new NotificationChannel(mTestNotificationChannel.getId(),
1307 mTestNotificationChannel.getName(), IMPORTANCE_NONE);
1308 mService.setRankingHelper(mRankingHelper);
1309 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1310 eq(mTestNotificationChannel.getId()), anyBoolean()))
1311 .thenReturn(existingChannel);
1312
1313 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
1314 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1315 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1316
1317 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED,
1318 captor.getValue().getAction());
1319 assertEquals(PKG, captor.getValue().getPackage());
1320 assertEquals(mTestNotificationChannel.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001321 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001322 assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1323 }
1324
1325 @Test
1326 public void testUpdateChannelNoNotifyCreatorOtherChanges() throws Exception {
1327 NotificationChannel existingChannel =
1328 new NotificationChannel(mTestNotificationChannel.getId(),
1329 mTestNotificationChannel.getName(), IMPORTANCE_MAX);
1330 mService.setRankingHelper(mRankingHelper);
1331 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1332 eq(mTestNotificationChannel.getId()), anyBoolean()))
1333 .thenReturn(existingChannel);
1334
1335 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
1336 verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
1337 }
1338
1339 @Test
1340 public void testUpdateGroupNotifyCreatorBlock() throws Exception {
1341 NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
1342 mService.setRankingHelper(mRankingHelper);
1343 when(mRankingHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
1344 .thenReturn(existing);
1345
1346 NotificationChannelGroup updated = new NotificationChannelGroup("id", "name");
1347 updated.setBlocked(true);
1348
1349 mBinderService.updateNotificationChannelGroupForPackage(PKG, 0, updated);
1350 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1351 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1352
1353 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED,
1354 captor.getValue().getAction());
1355 assertEquals(PKG, captor.getValue().getPackage());
1356 assertEquals(existing.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001357 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001358 assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1359 }
1360
1361 @Test
1362 public void testUpdateGroupNotifyCreatorUnblock() throws Exception {
1363 NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
1364 existing.setBlocked(true);
1365 mService.setRankingHelper(mRankingHelper);
1366 when(mRankingHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
1367 .thenReturn(existing);
1368
1369 mBinderService.updateNotificationChannelGroupForPackage(
1370 PKG, 0, new NotificationChannelGroup("id", "name"));
1371 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1372 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1373
1374 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED,
1375 captor.getValue().getAction());
1376 assertEquals(PKG, captor.getValue().getPackage());
1377 assertEquals(existing.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001378 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001379 assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1380 }
1381
1382 @Test
1383 public void testUpdateGroupNoNotifyCreatorOtherChanges() throws Exception {
1384 NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
1385 mService.setRankingHelper(mRankingHelper);
1386 when(mRankingHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
1387 .thenReturn(existing);
1388
1389 mBinderService.updateNotificationChannelGroupForPackage(
1390 PKG, 0, new NotificationChannelGroup("id", "new name"));
1391 verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
1392 }
1393
1394 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001395 public void testCreateChannelNotifyListener() throws Exception {
1396 List<String> associations = new ArrayList<>();
1397 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001398 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds503ed942017-10-04 16:04:56 -04001399 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001400 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1401 eq(mTestNotificationChannel.getId()), anyBoolean()))
1402 .thenReturn(mTestNotificationChannel);
1403 NotificationChannel channel2 = new NotificationChannel("a", "b", IMPORTANCE_LOW);
1404 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1405 eq(channel2.getId()), anyBoolean()))
1406 .thenReturn(channel2);
1407
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001408 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001409 mBinderService.createNotificationChannels(PKG,
1410 new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001411 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001412 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001413 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001414 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001415 eq(Process.myUserHandle()), eq(channel2),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001416 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
1417 }
1418
1419 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001420 public void testCreateChannelGroupNotifyListener() throws Exception {
1421 List<String> associations = new ArrayList<>();
1422 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001423 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds503ed942017-10-04 16:04:56 -04001424 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001425 NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
1426 NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
1427
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001428 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001429 mBinderService.createNotificationChannelGroups(PKG,
1430 new ParceledListSlice(Arrays.asList(group1, group2)));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001431 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001432 eq(Process.myUserHandle()), eq(group1),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001433 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001434 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001435 eq(Process.myUserHandle()), eq(group2),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001436 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
1437 }
1438
1439 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001440 public void testUpdateChannelNotifyListener() throws Exception {
1441 List<String> associations = new ArrayList<>();
1442 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001443 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds503ed942017-10-04 16:04:56 -04001444 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001445 mTestNotificationChannel.setLightColor(Color.CYAN);
1446 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1447 eq(mTestNotificationChannel.getId()), anyBoolean()))
1448 .thenReturn(mTestNotificationChannel);
1449
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001450 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001451 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001452 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001453 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001454 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1455 }
1456
1457 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001458 public void testDeleteChannelNotifyListener() throws Exception {
1459 List<String> associations = new ArrayList<>();
1460 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001461 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds503ed942017-10-04 16:04:56 -04001462 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001463 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1464 eq(mTestNotificationChannel.getId()), anyBoolean()))
1465 .thenReturn(mTestNotificationChannel);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001466 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001467 mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001468 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001469 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001470 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
1471 }
1472
1473 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001474 public void testDeleteChannelGroupNotifyListener() throws Exception {
1475 List<String> associations = new ArrayList<>();
1476 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001477 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001478 NotificationChannelGroup ncg = new NotificationChannelGroup("a", "b/c");
Julia Reynolds503ed942017-10-04 16:04:56 -04001479 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001480 when(mRankingHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt()))
1481 .thenReturn(ncg);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001482 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001483 mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001484 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001485 eq(Process.myUserHandle()), eq(ncg),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001486 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
1487 }
1488
1489 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001490 public void testUpdateNotificationChannelFromPrivilegedListener_success() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001491 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001492 List<String> associations = new ArrayList<>();
1493 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001494 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001495 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
1496 eq(mTestNotificationChannel.getId()), anyBoolean()))
1497 .thenReturn(mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001498
1499 mBinderService.updateNotificationChannelFromPrivilegedListener(
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001500 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001501
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001502 verify(mRankingHelper, times(1)).updateNotificationChannel(
1503 anyString(), anyInt(), any(), anyBoolean());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001504
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001505 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001506 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001507 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1508 }
1509
1510 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001511 public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001512 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001513 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001514 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001515
1516 try {
1517 mBinderService.updateNotificationChannelFromPrivilegedListener(
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001518 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001519 fail("listeners that don't have a companion device shouldn't be able to call this");
1520 } catch (SecurityException e) {
1521 // pass
1522 }
1523
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001524 verify(mRankingHelper, never()).updateNotificationChannel(
1525 anyString(), anyInt(), any(), anyBoolean());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001526
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001527 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001528 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
1529 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1530 }
1531
1532 @Test
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001533 public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001534 mService.setRankingHelper(mRankingHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001535 List<String> associations = new ArrayList<>();
1536 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001537 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001538 mListener = mock(ManagedServices.ManagedServiceInfo.class);
Julia Reynolds4da79702017-06-01 11:06:10 -04001539 mListener.component = new ComponentName(PKG, PKG);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001540 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001541 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001542
1543 try {
1544 mBinderService.updateNotificationChannelFromPrivilegedListener(
1545 null, PKG, UserHandle.ALL, mTestNotificationChannel);
1546 fail("incorrectly allowed a change to a user listener cannot see");
1547 } catch (SecurityException e) {
1548 // pass
1549 }
1550
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001551 verify(mRankingHelper, never()).updateNotificationChannel(
1552 anyString(), anyInt(), any(), anyBoolean());
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001553
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001554 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001555 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001556 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1557 }
1558
1559 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001560 public void testGetNotificationChannelFromPrivilegedListener_success() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001561 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001562 List<String> associations = new ArrayList<>();
1563 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001564 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001565
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001566 mBinderService.getNotificationChannelsFromPrivilegedListener(
1567 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001568
1569 verify(mRankingHelper, times(1)).getNotificationChannels(
1570 anyString(), anyInt(), anyBoolean());
1571 }
1572
1573 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001574 public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001575 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001576 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001577 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001578
1579 try {
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001580 mBinderService.getNotificationChannelsFromPrivilegedListener(
1581 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001582 fail("listeners that don't have a companion device shouldn't be able to call this");
1583 } catch (SecurityException e) {
1584 // pass
1585 }
1586
1587 verify(mRankingHelper, never()).getNotificationChannels(
1588 anyString(), anyInt(), anyBoolean());
1589 }
1590
1591 @Test
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001592 public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001593 mService.setRankingHelper(mRankingHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001594 List<String> associations = new ArrayList<>();
1595 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001596 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001597 mListener = mock(ManagedServices.ManagedServiceInfo.class);
1598 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001599 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001600
1601 try {
1602 mBinderService.getNotificationChannelsFromPrivilegedListener(
1603 null, PKG, Process.myUserHandle());
1604 fail("listener getting channels from a user they cannot see");
1605 } catch (SecurityException e) {
1606 // pass
1607 }
1608
1609 verify(mRankingHelper, never()).getNotificationChannels(
1610 anyString(), anyInt(), anyBoolean());
1611 }
1612
1613 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001614 public void testGetNotificationChannelGroupsFromPrivilegedListener_success() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001615 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001616 List<String> associations = new ArrayList<>();
1617 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001618 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001619
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001620 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1621 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001622
1623 verify(mRankingHelper, times(1)).getNotificationChannelGroups(anyString(), anyInt());
1624 }
1625
1626 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001627 public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001628 mService.setRankingHelper(mRankingHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001629 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001630 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001631
1632 try {
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001633 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1634 null, PKG, Process.myUserHandle());
1635 fail("listeners that don't have a companion device shouldn't be able to call this");
1636 } catch (SecurityException e) {
1637 // pass
1638 }
1639
1640 verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
1641 }
1642
1643 @Test
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001644 public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001645 mService.setRankingHelper(mRankingHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001646 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001647 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001648 mListener = mock(ManagedServices.ManagedServiceInfo.class);
1649 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001650 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001651
1652 try {
1653 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1654 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001655 fail("listeners that don't have a companion device shouldn't be able to call this");
1656 } catch (SecurityException e) {
1657 // pass
1658 }
1659
1660 verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
1661 }
Julia Reynoldsda781472017-04-12 09:41:16 -04001662
1663 @Test
Julia Reynoldsda781472017-04-12 09:41:16 -04001664 public void testHasCompanionDevice_failure() throws Exception {
1665 when(mCompanionMgr.getAssociations(anyString(), anyInt())).thenThrow(
1666 new IllegalArgumentException());
Julia Reynolds503ed942017-10-04 16:04:56 -04001667 mService.hasCompanionDevice(mListener);
Julia Reynoldsda781472017-04-12 09:41:16 -04001668 }
Julia Reynolds727a7282017-04-13 10:54:01 -04001669
1670 @Test
Julia Reynolds727a7282017-04-13 10:54:01 -04001671 public void testHasCompanionDevice_noService() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001672 mService = new TestableNotificationManagerService(mContext);
Julia Reynolds727a7282017-04-13 10:54:01 -04001673
Julia Reynolds503ed942017-10-04 16:04:56 -04001674 assertFalse(mService.hasCompanionDevice(mListener));
Julia Reynolds727a7282017-04-13 10:54:01 -04001675 }
1676
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001677 @Test
1678 public void testSnoozeRunnable_snoozeNonGrouped() throws Exception {
1679 final NotificationRecord nonGrouped = generateNotificationRecord(
1680 mTestNotificationChannel, 1, null, false);
1681 final NotificationRecord grouped = generateNotificationRecord(
1682 mTestNotificationChannel, 2, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001683 mService.addNotification(grouped);
1684 mService.addNotification(nonGrouped);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001685
1686 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001687 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001688 nonGrouped.getKey(), 100, null);
1689 snoozeNotificationRunnable.run();
1690
1691 // only snooze the one notification
1692 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
Julia Reynolds503ed942017-10-04 16:04:56 -04001693 assertTrue(nonGrouped.getStats().hasSnoozed());
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001694 }
1695
1696 @Test
1697 public void testSnoozeRunnable_snoozeSummary_withChildren() throws Exception {
1698 final NotificationRecord parent = generateNotificationRecord(
1699 mTestNotificationChannel, 1, "group", true);
1700 final NotificationRecord child = generateNotificationRecord(
1701 mTestNotificationChannel, 2, "group", false);
1702 final NotificationRecord child2 = generateNotificationRecord(
1703 mTestNotificationChannel, 3, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001704 mService.addNotification(parent);
1705 mService.addNotification(child);
1706 mService.addNotification(child2);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001707
1708 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001709 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001710 parent.getKey(), 100, null);
1711 snoozeNotificationRunnable.run();
1712
1713 // snooze parent and children
1714 verify(mSnoozeHelper, times(3)).snooze(any(NotificationRecord.class), anyLong());
1715 }
1716
1717 @Test
1718 public void testSnoozeRunnable_snoozeGroupChild_fellowChildren() throws Exception {
1719 final NotificationRecord parent = generateNotificationRecord(
1720 mTestNotificationChannel, 1, "group", true);
1721 final NotificationRecord child = generateNotificationRecord(
1722 mTestNotificationChannel, 2, "group", false);
1723 final NotificationRecord child2 = generateNotificationRecord(
1724 mTestNotificationChannel, 3, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001725 mService.addNotification(parent);
1726 mService.addNotification(child);
1727 mService.addNotification(child2);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001728
1729 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001730 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001731 child2.getKey(), 100, null);
1732 snoozeNotificationRunnable.run();
1733
1734 // only snooze the one child
1735 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
1736 }
1737
1738 @Test
1739 public void testSnoozeRunnable_snoozeGroupChild_onlyChildOfSummary() throws Exception {
1740 final NotificationRecord parent = generateNotificationRecord(
1741 mTestNotificationChannel, 1, "group", true);
1742 assertTrue(parent.sbn.getNotification().isGroupSummary());
1743 final NotificationRecord child = generateNotificationRecord(
1744 mTestNotificationChannel, 2, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001745 mService.addNotification(parent);
1746 mService.addNotification(child);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001747
1748 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001749 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001750 child.getKey(), 100, null);
1751 snoozeNotificationRunnable.run();
1752
1753 // snooze child and summary
1754 verify(mSnoozeHelper, times(2)).snooze(any(NotificationRecord.class), anyLong());
1755 }
1756
1757 @Test
1758 public void testSnoozeRunnable_snoozeGroupChild_noOthersInGroup() throws Exception {
1759 final NotificationRecord child = generateNotificationRecord(
1760 mTestNotificationChannel, 2, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001761 mService.addNotification(child);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001762
1763 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001764 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001765 child.getKey(), 100, null);
1766 snoozeNotificationRunnable.run();
1767
1768 // snooze child only
1769 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
1770 }
1771
1772 @Test
1773 public void testPostGroupChild_unsnoozeParent() throws Exception {
1774 final NotificationRecord child = generateNotificationRecord(
1775 mTestNotificationChannel, 2, "group", false);
1776
1777 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
1778 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
1779 waitForIdle();
1780
1781 verify(mSnoozeHelper, times(1)).repostGroupSummary(
1782 anyString(), anyInt(), eq(child.getGroupKey()));
1783 }
1784
1785 @Test
1786 public void testPostNonGroup_noUnsnoozing() throws Exception {
1787 final NotificationRecord record = generateNotificationRecord(
1788 mTestNotificationChannel, 2, null, false);
1789
1790 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
1791 record.sbn.getId(), record.sbn.getNotification(), record.sbn.getUserId());
1792 waitForIdle();
1793
1794 verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
1795 }
1796
1797 @Test
1798 public void testPostGroupSummary_noUnsnoozing() throws Exception {
1799 final NotificationRecord parent = generateNotificationRecord(
1800 mTestNotificationChannel, 2, "group", true);
1801
1802 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
1803 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
1804 waitForIdle();
1805
1806 verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
1807 }
Julia Reynoldsb852e562017-06-06 16:14:18 -04001808
1809 @Test
Julia Reynolds92febc32017-10-26 11:30:31 -04001810 public void testSetListenerAccessForUser() throws Exception {
1811 UserHandle user = UserHandle.of(10);
1812 ComponentName c = ComponentName.unflattenFromString("package/Component");
1813 try {
1814 mBinderService.setNotificationListenerAccessGrantedForUser(
1815 c, user.getIdentifier(), true);
1816 } catch (SecurityException e) {
1817 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1818 throw e;
1819 }
1820 }
1821
1822 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
1823 verify(mListeners, times(1)).setPackageOrComponentEnabled(
1824 c.flattenToString(), user.getIdentifier(), true, true);
1825 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1826 c.flattenToString(), user.getIdentifier(), false, true);
1827 verify(mAssistants, never()).setPackageOrComponentEnabled(
1828 any(), anyInt(), anyBoolean(), anyBoolean());
1829 }
1830
1831 @Test
1832 public void testSetAssistantAccessForUser() throws Exception {
1833 UserHandle user = UserHandle.of(10);
1834 ComponentName c = ComponentName.unflattenFromString("package/Component");
1835 try {
1836 mBinderService.setNotificationAssistantAccessGrantedForUser(
1837 c, user.getIdentifier(), true);
1838 } catch (SecurityException e) {
1839 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1840 throw e;
1841 }
1842 }
1843
1844 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
1845 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
1846 c.flattenToString(), user.getIdentifier(), true, true);
1847 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1848 c.flattenToString(), user.getIdentifier(), false, true);
1849 verify(mListeners, never()).setPackageOrComponentEnabled(
1850 any(), anyInt(), anyBoolean(), anyBoolean());
1851 }
1852
1853 @Test
1854 public void testSetDndAccessForUser() throws Exception {
1855 UserHandle user = UserHandle.of(10);
1856 ComponentName c = ComponentName.unflattenFromString("package/Component");
1857 try {
1858 mBinderService.setNotificationPolicyAccessGrantedForUser(
1859 c.getPackageName(), user.getIdentifier(), true);
1860 } catch (SecurityException e) {
1861 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1862 throw e;
1863 }
1864 }
1865
1866 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
1867 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1868 c.getPackageName(), user.getIdentifier(), true, true);
1869 verify(mAssistants, never()).setPackageOrComponentEnabled(
1870 any(), anyInt(), anyBoolean(), anyBoolean());
1871 verify(mListeners, never()).setPackageOrComponentEnabled(
1872 any(), anyInt(), anyBoolean(), anyBoolean());
1873 }
1874
1875 @Test
Julia Reynoldsb852e562017-06-06 16:14:18 -04001876 public void testSetListenerAccess() throws Exception {
1877 ComponentName c = ComponentName.unflattenFromString("package/Component");
1878 try {
1879 mBinderService.setNotificationListenerAccessGranted(c, true);
1880 } catch (SecurityException e) {
1881 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1882 throw e;
1883 }
1884 }
1885
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001886 verify(mListeners, times(1)).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001887 c.flattenToString(), 0, true, true);
1888 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1889 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001890 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001891 any(), anyInt(), anyBoolean(), anyBoolean());
1892 }
1893
1894 @Test
1895 public void testSetAssistantAccess() throws Exception {
1896 ComponentName c = ComponentName.unflattenFromString("package/Component");
1897 try {
1898 mBinderService.setNotificationAssistantAccessGranted(c, true);
1899 } catch (SecurityException e) {
1900 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1901 throw e;
1902 }
1903 }
1904
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001905 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001906 c.flattenToString(), 0, true, true);
1907 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1908 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001909 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001910 any(), anyInt(), anyBoolean(), anyBoolean());
1911 }
1912
1913 @Test
1914 public void testSetDndAccess() throws Exception {
1915 ComponentName c = ComponentName.unflattenFromString("package/Component");
1916 try {
1917 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
1918 } catch (SecurityException e) {
1919 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1920 throw e;
1921 }
1922 }
1923
1924 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1925 c.getPackageName(), 0, true, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001926 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001927 any(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001928 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001929 any(), anyInt(), anyBoolean(), anyBoolean());
1930 }
Julia Reynolds68263d12017-06-21 14:21:19 -04001931
1932 @Test
1933 public void testSetListenerAccess_doesNothingOnLowRam() throws Exception {
1934 when(mActivityManager.isLowRamDevice()).thenReturn(true);
1935 ComponentName c = ComponentName.unflattenFromString("package/Component");
1936 mBinderService.setNotificationListenerAccessGranted(c, true);
1937
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001938 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001939 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04001940 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001941 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001942 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04001943 any(), anyInt(), anyBoolean(), anyBoolean());
1944 }
1945
1946 @Test
1947 public void testSetAssistantAccess_doesNothingOnLowRam() throws Exception {
1948 when(mActivityManager.isLowRamDevice()).thenReturn(true);
1949 ComponentName c = ComponentName.unflattenFromString("package/Component");
1950 mBinderService.setNotificationAssistantAccessGranted(c, true);
1951
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001952 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001953 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04001954 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001955 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001956 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04001957 any(), anyInt(), anyBoolean(), anyBoolean());
1958 }
1959
1960 @Test
1961 public void testSetDndAccess_doesNothingOnLowRam() throws Exception {
1962 when(mActivityManager.isLowRamDevice()).thenReturn(true);
1963 ComponentName c = ComponentName.unflattenFromString("package/Component");
1964 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
1965
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001966 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001967 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04001968 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04001969 anyString(), anyInt(), anyBoolean(), anyBoolean());
1970 verify(mAssistants, never()).setPackageOrComponentEnabled(
1971 any(), anyInt(), anyBoolean(), anyBoolean());
1972 }
1973
1974 @Test
1975 public void testSetListenerAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
1976 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
1977 when(mActivityManager.isLowRamDevice()).thenReturn(true);
1978 ComponentName c = ComponentName.unflattenFromString("package/Component");
1979 try {
1980 mBinderService.setNotificationListenerAccessGranted(c, true);
1981 } catch (SecurityException e) {
1982 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1983 throw e;
1984 }
1985 }
1986
1987 verify(mListeners, times(1)).setPackageOrComponentEnabled(
1988 c.flattenToString(), 0, true, true);
1989 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04001990 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001991 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04001992 any(), anyInt(), anyBoolean(), anyBoolean());
1993 }
Julia Reynolds8aebf352017-06-26 11:35:33 -04001994
1995 @Test
Julia Reynoldse1816412017-10-24 10:39:11 -04001996 public void testSetAssistantAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
1997 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
1998 when(mActivityManager.isLowRamDevice()).thenReturn(true);
1999 ComponentName c = ComponentName.unflattenFromString("package/Component");
2000 try {
2001 mBinderService.setNotificationAssistantAccessGranted(c, true);
2002 } catch (SecurityException e) {
2003 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2004 throw e;
2005 }
2006 }
2007
2008 verify(mListeners, never()).setPackageOrComponentEnabled(
2009 anyString(), anyInt(), anyBoolean(), anyBoolean());
2010 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2011 c.flattenToString(), 0, false, true);
2012 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
2013 c.flattenToString(), 0, true, true);
2014 }
2015
2016 @Test
2017 public void testSetDndAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
2018 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
2019 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2020 ComponentName c = ComponentName.unflattenFromString("package/Component");
2021 try {
2022 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
2023 } catch (SecurityException e) {
2024 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2025 throw e;
2026 }
2027 }
2028
2029 verify(mListeners, never()).setPackageOrComponentEnabled(
2030 anyString(), anyInt(), anyBoolean(), anyBoolean());
2031 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2032 c.getPackageName(), 0, true, true);
2033 verify(mAssistants, never()).setPackageOrComponentEnabled(
2034 any(), anyInt(), anyBoolean(), anyBoolean());
2035 }
2036
2037 @Test
Julia Reynolds8aebf352017-06-26 11:35:33 -04002038 public void testOnlyAutogroupIfGroupChanged_noPriorNoti_autogroups() throws Exception {
2039 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002040 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002041 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002042 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002043 runnable.run();
2044 waitForIdle();
2045
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002046 verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002047 }
2048
2049 @Test
2050 public void testOnlyAutogroupIfGroupChanged_groupChanged_autogroups()
2051 throws Exception {
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002052 NotificationRecord r =
2053 generateNotificationRecord(mTestNotificationChannel, 0, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002054 mService.addNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002055
2056 r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002057 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002058 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002059 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002060 runnable.run();
2061 waitForIdle();
2062
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002063 verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002064 }
2065
2066 @Test
2067 public void testOnlyAutogroupIfGroupChanged_noGroupChanged_autogroups()
2068 throws Exception {
Julia Reynolds4db59552017-06-30 13:34:01 -04002069 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group",
2070 false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002071 mService.addNotification(r);
2072 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002073
2074 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002075 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002076 runnable.run();
2077 waitForIdle();
2078
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002079 verify(mGroupHelper, never()).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002080 }
Beverly40239d92017-07-07 10:20:41 -04002081
Julia Reynolds4db59552017-06-30 13:34:01 -04002082 @Test
2083 public void testNoFakeColorizedPermission() throws Exception {
2084 when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED);
2085 Notification.Builder nb = new Notification.Builder(mContext,
2086 mTestNotificationChannel.getId())
2087 .setContentTitle("foo")
2088 .setColorized(true)
2089 .setFlag(Notification.FLAG_CAN_COLORIZE, true)
2090 .setSmallIcon(android.R.drawable.sym_def_app_icon);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002091 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
2092 nb.build(), new UserHandle(mUid), null, 0);
Julia Reynolds4db59552017-06-30 13:34:01 -04002093 NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
2094
2095 mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
2096 nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
2097 waitForIdle();
2098
Julia Reynolds503ed942017-10-04 16:04:56 -04002099 NotificationRecord posted = mService.findNotificationLocked(
Julia Reynolds4db59552017-06-30 13:34:01 -04002100 PKG, null, nr.sbn.getId(), nr.sbn.getUserId());
2101
2102 assertFalse(posted.getNotification().isColorized());
2103 }
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002104
2105 @Test
2106 public void testGetNotificationCountLocked() throws Exception {
2107 for (int i = 0; i < 20; i++) {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002108 NotificationRecord r =
2109 generateNotificationRecord(mTestNotificationChannel, i, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002110 mService.addEnqueuedNotification(r);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002111 }
2112 for (int i = 0; i < 20; i++) {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002113 NotificationRecord r =
2114 generateNotificationRecord(mTestNotificationChannel, i, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002115 mService.addNotification(r);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002116 }
2117
2118 // another package
2119 Notification n =
2120 new Notification.Builder(mContext, mTestNotificationChannel.getId())
2121 .setSmallIcon(android.R.drawable.sym_def_app_icon)
2122 .build();
2123
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002124 StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "tag", mUid, 0,
2125 n, new UserHandle(mUid), null, 0);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002126 NotificationRecord otherPackage =
2127 new NotificationRecord(mContext, sbn, mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002128 mService.addEnqueuedNotification(otherPackage);
2129 mService.addNotification(otherPackage);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002130
2131 // Same notifications are enqueued as posted, everything counts b/c id and tag don't match
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002132 int userId = new UserHandle(mUid).getIdentifier();
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002133 assertEquals(40,
Julia Reynolds503ed942017-10-04 16:04:56 -04002134 mService.getNotificationCountLocked(PKG, userId, 0, null));
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002135 assertEquals(40,
Julia Reynolds503ed942017-10-04 16:04:56 -04002136 mService.getNotificationCountLocked(PKG, userId, 0, "tag2"));
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002137 assertEquals(2,
Julia Reynolds503ed942017-10-04 16:04:56 -04002138 mService.getNotificationCountLocked("a", userId, 0, "banana"));
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002139
2140 // exclude a known notification - it's excluded from only the posted list, not enqueued
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002141 assertEquals(39,
Julia Reynolds503ed942017-10-04 16:04:56 -04002142 mService.getNotificationCountLocked(PKG, userId, 0, "tag"));
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002143 }
2144
2145 @Test
Julia Reynolds51710712017-07-19 13:48:07 -04002146 public void testAddAutogroup_requestsSort() throws Exception {
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002147 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002148 mService.setRankingHandler(rh);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002149
2150 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002151 mService.addNotification(r);
2152 mService.addAutogroupKeyLocked(r.getKey());
Julia Reynolds51710712017-07-19 13:48:07 -04002153
2154 verify(rh, times(1)).requestSort();
2155 }
2156
2157 @Test
2158 public void testRemoveAutogroup_requestsSort() throws Exception {
2159 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002160 mService.setRankingHandler(rh);
Julia Reynolds51710712017-07-19 13:48:07 -04002161
2162 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2163 r.setOverrideGroupKey("TEST");
Julia Reynolds503ed942017-10-04 16:04:56 -04002164 mService.addNotification(r);
2165 mService.removeAutogroupKeyLocked(r.getKey());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002166
Julia Reynolds51710712017-07-19 13:48:07 -04002167 verify(rh, times(1)).requestSort();
2168 }
2169
2170 @Test
2171 public void testReaddAutogroup_noSort() throws Exception {
2172 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002173 mService.setRankingHandler(rh);
Julia Reynolds51710712017-07-19 13:48:07 -04002174
2175 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2176 r.setOverrideGroupKey("TEST");
Julia Reynolds503ed942017-10-04 16:04:56 -04002177 mService.addNotification(r);
2178 mService.addAutogroupKeyLocked(r.getKey());
Julia Reynolds51710712017-07-19 13:48:07 -04002179
2180 verify(rh, never()).requestSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002181 }
2182
2183 @Test
2184 public void testHandleRankingSort_sendsUpdateOnSignalExtractorChange() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04002185 mService.setRankingHelper(mRankingHelper);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002186 NotificationManagerService.WorkerHandler handler = mock(
2187 NotificationManagerService.WorkerHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002188 mService.setHandler(handler);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002189
2190 Map<String, Answer> answers = getSignalExtractorSideEffects();
2191 for (String message : answers.keySet()) {
Julia Reynolds503ed942017-10-04 16:04:56 -04002192 mService.clearNotifications();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002193 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002194 mService.addNotification(r);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002195
2196 doAnswer(answers.get(message)).when(mRankingHelper).extractSignals(r);
2197
Julia Reynolds503ed942017-10-04 16:04:56 -04002198 mService.handleRankingSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002199 }
2200 verify(handler, times(answers.size())).scheduleSendRankingUpdate();
2201 }
2202
2203 @Test
2204 public void testHandleRankingSort_noUpdateWhenNoSignalChange() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04002205 mService.setRankingHelper(mRankingHelper);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002206 NotificationManagerService.WorkerHandler handler = mock(
2207 NotificationManagerService.WorkerHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002208 mService.setHandler(handler);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002209
2210 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002211 mService.addNotification(r);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002212
Julia Reynolds503ed942017-10-04 16:04:56 -04002213 mService.handleRankingSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002214 verify(handler, never()).scheduleSendRankingUpdate();
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002215 }
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002216
2217 @Test
2218 public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception {
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002219 final String upgradeXml = "<notification-policy version=\"1\">"
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002220 + "<ranking></ranking>"
2221 + "<enabled_listeners>"
2222 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
2223 + "</enabled_listeners>"
2224 + "<enabled_assistants>"
2225 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
2226 + "</enabled_assistants>"
2227 + "<dnd_apps>"
2228 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
2229 + "</dnd_apps>"
2230 + "</notification-policy>";
Julia Reynolds503ed942017-10-04 16:04:56 -04002231 mService.readPolicyXml(
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002232 new BufferedInputStream(new ByteArrayInputStream(upgradeXml.getBytes())), false);
Kristian Monsen30f59b22018-04-09 10:27:16 +02002233 verify(mListeners, times(1)).readXml(any(), any());
2234 verify(mConditionProviders, times(1)).readXml(any(), any());
2235 verify(mAssistants, times(1)).readXml(any(), any());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002236
2237 // numbers are inflated for setup
2238 verify(mListeners, times(1)).migrateToXml();
2239 verify(mConditionProviders, times(1)).migrateToXml();
2240 verify(mAssistants, times(1)).migrateToXml();
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002241 verify(mAssistants, times(2)).ensureAssistant();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002242 }
2243
2244 @Test
2245 public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception {
2246 final String preupgradeXml = "<notification-policy version=\"1\">"
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002247 + "<ranking></ranking>"
2248 + "</notification-policy>";
Julia Reynolds503ed942017-10-04 16:04:56 -04002249 mService.readPolicyXml(
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002250 new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
Kristian Monsen30f59b22018-04-09 10:27:16 +02002251 verify(mListeners, never()).readXml(any(), any());
2252 verify(mConditionProviders, never()).readXml(any(), any());
2253 verify(mAssistants, never()).readXml(any(), any());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002254
2255 // numbers are inflated for setup
2256 verify(mListeners, times(2)).migrateToXml();
2257 verify(mConditionProviders, times(2)).migrateToXml();
2258 verify(mAssistants, times(2)).migrateToXml();
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002259 verify(mAssistants, times(2)).ensureAssistant();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002260 }
2261
Beverlyd4f96492017-08-02 13:36:11 -04002262
2263 @Test
2264 public void testLocaleChangedCallsUpdateDefaultZenModeRules() throws Exception {
2265 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002266 mService.mZenModeHelper = mZenModeHelper;
2267 mService.mLocaleChangeReceiver.onReceive(mContext,
Beverlyd4f96492017-08-02 13:36:11 -04002268 new Intent(Intent.ACTION_LOCALE_CHANGED));
2269
2270 verify(mZenModeHelper, times(1)).updateDefaultZenRules();
2271 }
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002272
2273 @Test
2274 public void testBumpFGImportance_noChannelChangePreOApp() throws Exception {
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002275 String preOPkg = PKG_N_MR1;
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002276 int preOUid = 145;
2277 final ApplicationInfo legacy = new ApplicationInfo();
2278 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
2279 when(mPackageManagerClient.getApplicationInfoAsUser(eq(preOPkg), anyInt(), anyInt()))
2280 .thenReturn(legacy);
2281 when(mPackageManagerClient.getPackageUidAsUser(eq(preOPkg), anyInt())).thenReturn(preOUid);
2282 getContext().setMockPackageManager(mPackageManagerClient);
2283
2284 Notification.Builder nb = new Notification.Builder(mContext,
2285 NotificationChannel.DEFAULT_CHANNEL_ID)
2286 .setContentTitle("foo")
2287 .setSmallIcon(android.R.drawable.sym_def_app_icon)
Julia Reynoldse5c60452018-04-30 14:41:36 -04002288 .setFlag(FLAG_FOREGROUND_SERVICE, true)
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002289 .setPriority(Notification.PRIORITY_MIN);
2290
2291 StatusBarNotification sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid,
2292 0, nb.build(), new UserHandle(preOUid), null, 0);
2293
2294 mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag",
2295 sbn.getId(), sbn.getNotification(), sbn.getUserId());
2296 waitForIdle();
2297 assertEquals(IMPORTANCE_LOW,
Julia Reynolds503ed942017-10-04 16:04:56 -04002298 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002299
2300 nb = new Notification.Builder(mContext)
2301 .setContentTitle("foo")
2302 .setSmallIcon(android.R.drawable.sym_def_app_icon)
Julia Reynoldse5c60452018-04-30 14:41:36 -04002303 .setFlag(FLAG_FOREGROUND_SERVICE, true)
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002304 .setPriority(Notification.PRIORITY_MIN);
2305
2306 sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid,
2307 0, nb.build(), new UserHandle(preOUid), null, 0);
2308
2309 mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag",
2310 sbn.getId(), sbn.getNotification(), sbn.getUserId());
2311 waitForIdle();
2312 assertEquals(IMPORTANCE_LOW,
Julia Reynolds503ed942017-10-04 16:04:56 -04002313 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002314
2315 NotificationChannel defaultChannel = mBinderService.getNotificationChannel(
2316 preOPkg, NotificationChannel.DEFAULT_CHANNEL_ID);
2317 assertEquals(IMPORTANCE_UNSPECIFIED, defaultChannel.getImportance());
2318 }
Julia Reynolds503ed942017-10-04 16:04:56 -04002319
2320 @Test
2321 public void testStats_updatedOnDirectReply() throws Exception {
2322 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2323 mService.addNotification(r);
2324
2325 mService.mNotificationDelegate.onNotificationDirectReplied(r.getKey());
2326 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasDirectReplied());
2327 }
2328
2329 @Test
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002330 public void testStats_updatedOnUserExpansion() throws Exception {
2331 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002332 mService.addNotification(r);
2333
2334 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), true, true);
2335 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
2336 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), true, false);
2337 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
2338 }
2339
2340 @Test
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002341 public void testStats_notUpdatedOnAutoExpansion() throws Exception {
2342 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2343 mService.addNotification(r);
2344
2345 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, true);
2346 assertFalse(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
2347 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, false);
2348 assertFalse(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
2349 }
2350
2351 @Test
Julia Reynolds503ed942017-10-04 16:04:56 -04002352 public void testStats_updatedOnViewSettings() throws Exception {
2353 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2354 mService.addNotification(r);
2355
2356 mService.mNotificationDelegate.onNotificationSettingsViewed(r.getKey());
2357 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasViewedSettings());
2358 }
2359
2360 @Test
2361 public void testStats_updatedOnVisibilityChanged() throws Exception {
2362 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2363 mService.addNotification(r);
2364
Dieter Hsud39f0d52018-04-14 02:08:30 +08002365 final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 1, 2, true);
Julia Reynolds503ed942017-10-04 16:04:56 -04002366 mService.mNotificationDelegate.onNotificationVisibilityChanged(
2367 new NotificationVisibility[] {nv}, new NotificationVisibility[]{});
2368 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasSeen());
2369 mService.mNotificationDelegate.onNotificationVisibilityChanged(
2370 new NotificationVisibility[] {}, new NotificationVisibility[]{nv});
2371 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasSeen());
2372 }
2373
2374 @Test
2375 public void testStats_dismissalSurface() throws Exception {
2376 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2377 mService.addNotification(r);
2378
Dieter Hsud39f0d52018-04-14 02:08:30 +08002379 final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
Julia Reynolds503ed942017-10-04 16:04:56 -04002380 mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.sbn.getTag(),
Dieter Hsud39f0d52018-04-14 02:08:30 +08002381 r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD, nv);
Julia Reynolds503ed942017-10-04 16:04:56 -04002382 waitForIdle();
2383
2384 assertEquals(NotificationStats.DISMISSAL_AOD, r.getStats().getDismissalSurface());
2385 }
2386
2387 @Test
2388 public void testUserSentimentChangeTriggersUpdate() throws Exception {
2389 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2390 mService.addNotification(r);
2391 NotificationManagerService.WorkerHandler handler = mock(
2392 NotificationManagerService.WorkerHandler.class);
2393 mService.setHandler(handler);
2394
2395 Bundle signals = new Bundle();
2396 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
2397 NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
2398 Adjustment adjustment = new Adjustment(
2399 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2400 mBinderService.applyAdjustmentFromAssistant(null, adjustment);
2401
2402 waitForIdle();
2403
2404 verify(handler, timeout(300).times(1)).scheduleSendRankingUpdate();
2405 }
Julia Reynolds7bcb57b2018-01-22 10:37:58 -05002406
2407 @Test
2408 public void testRecents() throws Exception {
2409 Set<NotifyingApp> expected = new HashSet<>();
2410
2411 final NotificationRecord oldest = new NotificationRecord(mContext,
2412 generateSbn("p", 1000, 9, 0), mTestNotificationChannel);
2413 mService.logRecentLocked(oldest);
2414 for (int i = 1; i <= 5; i++) {
2415 NotificationRecord r = new NotificationRecord(mContext,
2416 generateSbn("p" + i, i, i*100, 0), mTestNotificationChannel);
2417 expected.add(new NotifyingApp()
2418 .setPackage(r.sbn.getPackageName())
2419 .setUid(r.sbn.getUid())
2420 .setLastNotified(r.sbn.getPostTime()));
2421 mService.logRecentLocked(r);
2422 }
2423
2424 List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
2425 assertTrue(apps.size() == 5);
2426 for (NotifyingApp actual : apps) {
2427 assertTrue("got unexpected result: " + actual, expected.contains(actual));
2428 }
2429 }
2430
2431 @Test
2432 public void testRecentsNoDuplicatePackages() throws Exception {
2433 final NotificationRecord p1 = new NotificationRecord(mContext, generateSbn("p", 1, 1000, 0),
2434 mTestNotificationChannel);
2435 final NotificationRecord p2 = new NotificationRecord(mContext, generateSbn("p", 1, 2000, 0),
2436 mTestNotificationChannel);
2437
2438 mService.logRecentLocked(p1);
2439 mService.logRecentLocked(p2);
2440
2441 List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
2442 assertTrue(apps.size() == 1);
2443 NotifyingApp expected = new NotifyingApp().setPackage("p").setUid(1).setLastNotified(2000);
2444 assertEquals(expected, apps.get(0));
2445 }
2446
2447 @Test
2448 public void testRecentsWithDuplicatePackage() throws Exception {
2449 Set<NotifyingApp> expected = new HashSet<>();
2450
2451 final NotificationRecord oldest = new NotificationRecord(mContext,
2452 generateSbn("p", 1000, 9, 0), mTestNotificationChannel);
2453 mService.logRecentLocked(oldest);
2454 for (int i = 1; i <= 5; i++) {
2455 NotificationRecord r = new NotificationRecord(mContext,
2456 generateSbn("p" + i, i, i*100, 0), mTestNotificationChannel);
2457 expected.add(new NotifyingApp()
2458 .setPackage(r.sbn.getPackageName())
2459 .setUid(r.sbn.getUid())
2460 .setLastNotified(r.sbn.getPostTime()));
2461 mService.logRecentLocked(r);
2462 }
2463 NotificationRecord r = new NotificationRecord(mContext,
2464 generateSbn("p" + 3, 3, 300000, 0), mTestNotificationChannel);
2465 expected.remove(new NotifyingApp()
2466 .setPackage(r.sbn.getPackageName())
2467 .setUid(3)
2468 .setLastNotified(300));
2469 NotifyingApp newest = new NotifyingApp()
2470 .setPackage(r.sbn.getPackageName())
2471 .setUid(r.sbn.getUid())
2472 .setLastNotified(r.sbn.getPostTime());
2473 expected.add(newest);
2474 mService.logRecentLocked(r);
2475
2476 List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
2477 assertTrue(apps.size() == 5);
2478 for (NotifyingApp actual : apps) {
2479 assertTrue("got unexpected result: " + actual, expected.contains(actual));
2480 }
2481 assertEquals(newest, apps.get(0));
2482 }
2483
2484 @Test
2485 public void testRecentsMultiuser() throws Exception {
2486 final NotificationRecord user1 = new NotificationRecord(mContext,
2487 generateSbn("p", 1000, 9, 1), mTestNotificationChannel);
2488 mService.logRecentLocked(user1);
2489
2490 final NotificationRecord user2 = new NotificationRecord(mContext,
2491 generateSbn("p2", 100000, 9999, 2), mTestNotificationChannel);
2492 mService.logRecentLocked(user2);
2493
2494 assertEquals(0, mBinderService.getRecentNotifyingAppsForUser(0).getList().size());
2495 assertEquals(1, mBinderService.getRecentNotifyingAppsForUser(1).getList().size());
2496 assertEquals(1, mBinderService.getRecentNotifyingAppsForUser(2).getList().size());
2497
2498 assertTrue(mBinderService.getRecentNotifyingAppsForUser(2).getList().contains(
2499 new NotifyingApp()
2500 .setPackage(user2.sbn.getPackageName())
2501 .setUid(user2.sbn.getUid())
2502 .setLastNotified(user2.sbn.getPostTime())));
2503 }
Julia Reynoldsd78263d2018-01-30 10:40:41 -05002504
2505 @Test
2506 public void testRestore() throws Exception {
2507 int systemChecks = mService.countSystemChecks;
2508 mBinderService.applyRestore(null, UserHandle.USER_SYSTEM);
2509 assertEquals(1, mService.countSystemChecks - systemChecks);
2510 }
2511
2512 @Test
2513 public void testBackup() throws Exception {
2514 int systemChecks = mService.countSystemChecks;
2515 mBinderService.getBackupPayload(1);
2516 assertEquals(1, mService.countSystemChecks - systemChecks);
2517 }
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002518
2519 @Test
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002520 public void updateUriPermissions_update() throws Exception {
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002521 NotificationChannel c = new NotificationChannel(
2522 TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
2523 c.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
2524 Message message1 = new Message("", 0, "");
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002525 message1.setData("",
2526 ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1));
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002527 Message message2 = new Message("", 1, "");
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002528 message2.setData("",
2529 ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 2));
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002530
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002531 Notification.Builder nbA = new Notification.Builder(mContext, c.getId())
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002532 .setContentTitle("foo")
2533 .setSmallIcon(android.R.drawable.sym_def_app_icon)
2534 .setStyle(new Notification.MessagingStyle("")
2535 .addMessage(message1)
2536 .addMessage(message2));
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002537 NotificationRecord recordA = new NotificationRecord(mContext, new StatusBarNotification(
2538 PKG, PKG, 0, "tag", mUid, 0, nbA.build(), new UserHandle(mUid), null, 0), c);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002539
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002540 // First post means we grant access to both
2541 reset(mAm);
2542 when(mAm.newUriPermissionOwner(any())).thenReturn(new Binder());
2543 mService.updateUriPermissions(recordA, null, mContext.getPackageName(),
2544 UserHandle.USER_SYSTEM);
2545 verify(mAm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
2546 eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
2547 verify(mAm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
2548 eq(message2.getDataUri()), anyInt(), anyInt(), anyInt());
2549
2550 Notification.Builder nbB = new Notification.Builder(mContext, c.getId())
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002551 .setContentTitle("foo")
2552 .setSmallIcon(android.R.drawable.sym_def_app_icon)
2553 .setStyle(new Notification.MessagingStyle("").addMessage(message2));
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002554 NotificationRecord recordB = new NotificationRecord(mContext, new StatusBarNotification(PKG,
2555 PKG, 0, "tag", mUid, 0, nbB.build(), new UserHandle(mUid), null, 0), c);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002556
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002557 // Update means we drop access to first
2558 reset(mAm);
2559 mService.updateUriPermissions(recordB, recordA, mContext.getPackageName(),
2560 UserHandle.USER_SYSTEM);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002561 verify(mAm, times(1)).revokeUriPermissionFromOwner(any(), eq(message1.getDataUri()),
2562 anyInt(), anyInt());
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002563
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002564 // Update back means we grant access to first again
2565 reset(mAm);
2566 mService.updateUriPermissions(recordA, recordB, mContext.getPackageName(),
2567 UserHandle.USER_SYSTEM);
2568 verify(mAm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
2569 eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002570
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002571 // And update to empty means we drop everything
2572 reset(mAm);
2573 mService.updateUriPermissions(null, recordB, mContext.getPackageName(),
2574 UserHandle.USER_SYSTEM);
2575 verify(mAm, times(1)).revokeUriPermissionFromOwner(any(), eq(null),
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002576 anyInt(), anyInt());
2577 }
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05002578
2579 @Test
2580 public void testSetNotificationPolicy_preP_setOldFields() {
2581 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2582 mService.mZenModeHelper = mZenModeHelper;
2583 NotificationManager.Policy userPolicy =
2584 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2585 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2586
2587 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2588 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF);
2589
2590 int expected = SUPPRESSED_EFFECT_BADGE
2591 | SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF
Julia Reynoldseac2da22018-04-12 10:48:46 -04002592 | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_LIGHTS
2593 | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05002594 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
2595
2596 assertEquals(expected, actual);
2597 }
2598
2599 @Test
2600 public void testSetNotificationPolicy_preP_setNewFields() {
2601 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2602 mService.mZenModeHelper = mZenModeHelper;
2603 NotificationManager.Policy userPolicy =
2604 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2605 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2606
2607 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2608 SUPPRESSED_EFFECT_NOTIFICATION_LIST);
2609
2610 int expected = SUPPRESSED_EFFECT_BADGE;
2611 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
2612
2613 assertEquals(expected, actual);
2614 }
2615
2616 @Test
2617 public void testSetNotificationPolicy_preP_setOldNewFields() {
2618 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2619 mService.mZenModeHelper = mZenModeHelper;
2620 NotificationManager.Policy userPolicy =
2621 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2622 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2623
2624 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2625 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_STATUS_BAR);
2626
2627 int expected =
2628 SUPPRESSED_EFFECT_BADGE | SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_PEEK;
2629 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
2630
2631 assertEquals(expected, actual);
2632 }
2633
2634 @Test
2635 public void testSetNotificationPolicy_P_setOldFields() {
2636 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2637 mService.mZenModeHelper = mZenModeHelper;
2638 NotificationManager.Policy userPolicy =
2639 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2640 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2641
2642 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2643 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF);
2644
2645 int expected = SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF
2646 | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_AMBIENT
2647 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
2648 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
2649
2650 assertEquals(expected, actual);
2651 }
2652
2653 @Test
2654 public void testSetNotificationPolicy_P_setNewFields() {
2655 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2656 mService.mZenModeHelper = mZenModeHelper;
2657 NotificationManager.Policy userPolicy =
2658 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2659 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2660
2661 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2662 SUPPRESSED_EFFECT_NOTIFICATION_LIST | SUPPRESSED_EFFECT_AMBIENT
2663 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT);
2664
2665 int expected = SUPPRESSED_EFFECT_NOTIFICATION_LIST | SUPPRESSED_EFFECT_SCREEN_OFF
2666 | SUPPRESSED_EFFECT_AMBIENT | SUPPRESSED_EFFECT_LIGHTS
2667 | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
2668 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
2669
2670 assertEquals(expected, actual);
2671 }
2672
2673 @Test
2674 public void testSetNotificationPolicy_P_setOldNewFields() {
2675 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2676 mService.mZenModeHelper = mZenModeHelper;
2677 NotificationManager.Policy userPolicy =
2678 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2679 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2680
2681 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2682 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_STATUS_BAR);
2683
2684 int expected = SUPPRESSED_EFFECT_STATUS_BAR;
2685 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
2686
2687 assertEquals(expected, actual);
2688
2689 appPolicy = new NotificationManager.Policy(0, 0, 0,
2690 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_AMBIENT
2691 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT);
2692
2693 expected = SUPPRESSED_EFFECT_SCREEN_OFF | SUPPRESSED_EFFECT_AMBIENT
2694 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
2695 actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
2696
2697 assertEquals(expected, actual);
2698 }
Julia Reynolds7217dc92018-03-07 12:12:09 -05002699
2700 @Test
Julia Reynoldse5c60452018-04-30 14:41:36 -04002701 public void testVisualDifference_foreground() {
2702 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2703 .setContentTitle("foo");
2704 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2705 nb1.build(), new UserHandle(mUid), null, 0);
2706 NotificationRecord r1 =
2707 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2708
2709 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2710 .setFlag(FLAG_FOREGROUND_SERVICE, true)
2711 .setContentTitle("bar");
2712 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2713 nb2.build(), new UserHandle(mUid), null, 0);
2714 NotificationRecord r2 =
2715 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2716
2717 assertFalse(mService.isVisuallyInterruptive(r1, r2));
2718 }
2719
2720 @Test
Julia Reynolds7217dc92018-03-07 12:12:09 -05002721 public void testVisualDifference_diffTitle() {
2722 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2723 .setContentTitle("foo");
2724 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2725 nb1.build(), new UserHandle(mUid), null, 0);
2726 NotificationRecord r1 =
2727 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2728
2729 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2730 .setContentTitle("bar");
2731 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2732 nb2.build(), new UserHandle(mUid), null, 0);
2733 NotificationRecord r2 =
2734 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2735
2736 assertTrue(mService.isVisuallyInterruptive(r1, r2));
2737 }
2738
2739 @Test
Dan Sandler7d67bd42018-05-15 14:06:38 -04002740 public void testVisualDifference_inboxStyle() {
2741 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2742 .setStyle(new Notification.InboxStyle()
2743 .addLine("line1").addLine("line2"));
2744 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2745 nb1.build(), new UserHandle(mUid), null, 0);
2746 NotificationRecord r1 =
2747 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2748
2749 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2750 .setStyle(new Notification.InboxStyle()
2751 .addLine("line1").addLine("line2_changed"));
2752 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2753 nb2.build(), new UserHandle(mUid), null, 0);
2754 NotificationRecord r2 =
2755 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2756
2757 assertTrue(mService.isVisuallyInterruptive(r1, r2)); // line 2 changed unnoticed
2758
2759 Notification.Builder nb3 = new Notification.Builder(mContext, "")
2760 .setStyle(new Notification.InboxStyle()
2761 .addLine("line1"));
2762 StatusBarNotification sbn3 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2763 nb3.build(), new UserHandle(mUid), null, 0);
2764 NotificationRecord r3 =
2765 new NotificationRecord(mContext, sbn3, mock(NotificationChannel.class));
2766
2767 assertTrue(mService.isVisuallyInterruptive(r1, r3)); // line 2 removed unnoticed
2768
2769 Notification.Builder nb4 = new Notification.Builder(mContext, "")
2770 .setStyle(new Notification.InboxStyle()
2771 .addLine("line1").addLine("line2").addLine("line3"));
2772 StatusBarNotification sbn4 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2773 nb4.build(), new UserHandle(mUid), null, 0);
2774 NotificationRecord r4 =
2775 new NotificationRecord(mContext, sbn4, mock(NotificationChannel.class));
2776
2777 assertTrue(mService.isVisuallyInterruptive(r1, r4)); // line 3 added unnoticed
2778
2779 Notification.Builder nb5 = new Notification.Builder(mContext, "")
2780 .setContentText("not an inbox");
2781 StatusBarNotification sbn5 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2782 nb5.build(), new UserHandle(mUid), null, 0);
2783 NotificationRecord r5 =
2784 new NotificationRecord(mContext, sbn5, mock(NotificationChannel.class));
2785
2786 assertTrue(mService.isVisuallyInterruptive(r1, r5)); // changed Styles, went unnoticed
2787 }
2788
2789 @Test
Julia Reynolds7217dc92018-03-07 12:12:09 -05002790 public void testVisualDifference_diffText() {
2791 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2792 .setContentText("foo");
2793 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2794 nb1.build(), new UserHandle(mUid), null, 0);
2795 NotificationRecord r1 =
2796 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2797
2798 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2799 .setContentText("bar");
2800 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2801 nb2.build(), new UserHandle(mUid), null, 0);
2802 NotificationRecord r2 =
2803 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2804
2805 assertTrue(mService.isVisuallyInterruptive(r1, r2));
2806 }
2807
2808 @Test
Dan Sandler7d67bd42018-05-15 14:06:38 -04002809 public void testVisualDifference_sameText() {
2810 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2811 .setContentText("foo");
2812 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2813 nb1.build(), new UserHandle(mUid), null, 0);
2814 NotificationRecord r1 =
2815 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2816
2817 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2818 .setContentText("foo");
2819 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2820 nb2.build(), new UserHandle(mUid), null, 0);
2821 NotificationRecord r2 =
2822 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2823
2824 assertFalse(mService.isVisuallyInterruptive(r1, r2));
2825 }
2826
2827 @Test
2828 public void testVisualDifference_sameTextButStyled() {
2829 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2830 .setContentText(Html.fromHtml("<b>foo</b>"));
2831 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2832 nb1.build(), new UserHandle(mUid), null, 0);
2833 NotificationRecord r1 =
2834 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2835
2836 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2837 .setContentText(Html.fromHtml("<b>foo</b>"));
2838 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2839 nb2.build(), new UserHandle(mUid), null, 0);
2840 NotificationRecord r2 =
2841 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2842
2843 assertFalse(mService.isVisuallyInterruptive(r1, r2));
2844 }
2845
2846 @Test
2847 public void testVisualDifference_diffTextButStyled() {
2848 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2849 .setContentText(Html.fromHtml("<b>foo</b>"));
2850 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2851 nb1.build(), new UserHandle(mUid), null, 0);
2852 NotificationRecord r1 =
2853 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2854
2855 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2856 .setContentText(Html.fromHtml("<b>bar</b>"));
2857 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2858 nb2.build(), new UserHandle(mUid), null, 0);
2859 NotificationRecord r2 =
2860 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2861
2862 assertTrue(mService.isVisuallyInterruptive(r1, r2));
2863 }
2864
2865 @Test
Julia Reynolds7217dc92018-03-07 12:12:09 -05002866 public void testVisualDifference_diffProgress() {
2867 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2868 .setProgress(100, 90, false);
2869 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2870 nb1.build(), new UserHandle(mUid), null, 0);
2871 NotificationRecord r1 =
2872 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2873
2874 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2875 .setProgress(100, 100, false);
2876 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2877 nb2.build(), new UserHandle(mUid), null, 0);
2878 NotificationRecord r2 =
2879 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2880
2881 assertTrue(mService.isVisuallyInterruptive(r1, r2));
2882 }
2883
2884 @Test
2885 public void testVisualDifference_diffProgressNotDone() {
2886 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2887 .setProgress(100, 90, false);
2888 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2889 nb1.build(), new UserHandle(mUid), null, 0);
2890 NotificationRecord r1 =
2891 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2892
2893 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2894 .setProgress(100, 91, false);
2895 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2896 nb2.build(), new UserHandle(mUid), null, 0);
2897 NotificationRecord r2 =
2898 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2899
2900 assertFalse(mService.isVisuallyInterruptive(r1, r2));
2901 }
Beverly5a20a5e2018-03-06 15:02:44 -05002902
2903 @Test
Dan Sandler7d67bd42018-05-15 14:06:38 -04002904 public void testVisualDifference_sameProgressStillDone() {
2905 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2906 .setProgress(100, 100, false);
2907 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2908 nb1.build(), new UserHandle(mUid), null, 0);
2909 NotificationRecord r1 =
2910 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2911
2912 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2913 .setProgress(100, 100, false);
2914 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2915 nb2.build(), new UserHandle(mUid), null, 0);
2916 NotificationRecord r2 =
2917 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2918
2919 assertFalse(mService.isVisuallyInterruptive(r1, r2));
2920 }
2921
2922 @Test
Julia Reynoldsa4fb9da2018-06-04 12:27:58 -04002923 public void testVisualDifference_summary() {
2924 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2925 .setGroup("bananas")
2926 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
2927 .setContentText("foo");
2928 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2929 nb1.build(), new UserHandle(mUid), null, 0);
2930 NotificationRecord r1 =
2931 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2932
2933 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2934 .setGroup("bananas")
2935 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
2936 .setContentText("bar");
2937 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2938 nb2.build(), new UserHandle(mUid), null, 0);
2939 NotificationRecord r2 =
2940 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2941
2942 assertFalse(mService.isVisuallyInterruptive(r1, r2));
2943 }
2944
2945 @Test
Julia Reynolds6b302d02018-06-19 15:39:23 -04002946 public void testVisualDifference_summaryNewNotification() {
2947 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2948 .setGroup("bananas")
2949 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
2950 .setContentText("bar");
2951 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2952 nb2.build(), new UserHandle(mUid), null, 0);
2953 NotificationRecord r2 =
2954 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2955
2956 assertFalse(mService.isVisuallyInterruptive(null, r2));
2957 }
2958
2959 @Test
Beverly5a20a5e2018-03-06 15:02:44 -05002960 public void testHideAndUnhideNotificationsOnSuspendedPackageBroadcast() {
2961 // post 2 notification from this package
2962 final NotificationRecord notif1 = generateNotificationRecord(
2963 mTestNotificationChannel, 1, null, true);
2964 final NotificationRecord notif2 = generateNotificationRecord(
2965 mTestNotificationChannel, 2, null, false);
2966 mService.addNotification(notif1);
2967 mService.addNotification(notif2);
2968
2969 // on broadcast, hide the 2 notifications
2970 mService.simulatePackageSuspendBroadcast(true, PKG);
2971 ArgumentCaptor<List> captorHide = ArgumentCaptor.forClass(List.class);
2972 verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
2973 assertEquals(2, captorHide.getValue().size());
2974
2975 // on broadcast, unhide the 2 notifications
2976 mService.simulatePackageSuspendBroadcast(false, PKG);
2977 ArgumentCaptor<List> captorUnhide = ArgumentCaptor.forClass(List.class);
2978 verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
2979 assertEquals(2, captorUnhide.getValue().size());
2980 }
2981
2982 @Test
2983 public void testNoNotificationsHiddenOnSuspendedPackageBroadcast() {
2984 // post 2 notification from this package
2985 final NotificationRecord notif1 = generateNotificationRecord(
2986 mTestNotificationChannel, 1, null, true);
2987 final NotificationRecord notif2 = generateNotificationRecord(
2988 mTestNotificationChannel, 2, null, false);
2989 mService.addNotification(notif1);
2990 mService.addNotification(notif2);
2991
2992 // on broadcast, nothing is hidden since no notifications are of package "test_package"
2993 mService.simulatePackageSuspendBroadcast(true, "test_package");
2994 ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
2995 verify(mListeners, times(1)).notifyHiddenLocked(captor.capture());
2996 assertEquals(0, captor.getValue().size());
2997 }
Kristian Monsen30f59b22018-04-09 10:27:16 +02002998
2999 @Test
3000 public void testCanUseManagedServicesLowRamNoWatchNullPkg() {
3001 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3002 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3003 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3004 .thenReturn(new String[] {"a", "b", "c"});
3005 when(mContext.getResources()).thenReturn(mResources);
3006
3007 assertEquals(false, mService.canUseManagedServices(null));
3008 }
3009
3010 @Test
3011 public void testCanUseManagedServicesLowRamNoWatchValidPkg() {
3012 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3013 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3014 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3015 .thenReturn(new String[] {"a", "b", "c"});
3016 when(mContext.getResources()).thenReturn(mResources);
3017
3018 assertEquals(true, mService.canUseManagedServices("b"));
3019 }
3020
3021 @Test
3022 public void testCanUseManagedServicesLowRamNoWatchNoValidPkg() {
3023 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3024 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3025 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3026 .thenReturn(new String[] {"a", "b", "c"});
3027 when(mContext.getResources()).thenReturn(mResources);
3028
3029 assertEquals(false, mService.canUseManagedServices("d"));
3030 }
3031
3032 @Test
3033 public void testCanUseManagedServicesLowRamWatchNoValidPkg() {
3034 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
3035 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3036 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3037 .thenReturn(new String[] {"a", "b", "c"});
3038 when(mContext.getResources()).thenReturn(mResources);
3039
3040 assertEquals(true, mService.canUseManagedServices("d"));
3041 }
3042
3043 @Test
3044 public void testCanUseManagedServicesNoLowRamNoWatchValidPkg() {
3045 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3046 when(mActivityManager.isLowRamDevice()).thenReturn(false);
3047 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3048 .thenReturn(new String[] {"a", "b", "c"});
3049 when(mContext.getResources()).thenReturn(mResources);
3050
3051 assertEquals(true, mService.canUseManagedServices("d"));
3052 }
3053
3054 @Test
3055 public void testCanUseManagedServicesNoLowRamWatchValidPkg() {
3056 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
3057 when(mActivityManager.isLowRamDevice()).thenReturn(false);
3058 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3059 .thenReturn(new String[] {"a", "b", "c"});
3060 when(mContext.getResources()).thenReturn(mResources);
3061
3062 assertEquals(true, mService.canUseManagedServices("d"));
3063 }
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -04003064
3065 @Test
3066 public void testOnNotificationVisibilityChanged_triggersInterruptionUsageStat() {
3067 final NotificationRecord r = generateNotificationRecord(
3068 mTestNotificationChannel, 1, null, true);
3069 r.setTextChanged(true);
3070 mService.addNotification(r);
3071
3072 mService.mNotificationDelegate.onNotificationVisibilityChanged(new NotificationVisibility[]
3073 {NotificationVisibility.obtain(r.getKey(), 1, 1, true)},
3074 new NotificationVisibility[]{});
3075
3076 verify(mAppUsageStats).reportInterruptiveNotification(anyString(), anyString(), anyInt());
3077 }
3078
3079 @Test
3080 public void testSetNotificationsShownFromListener_triggersInterruptionUsageStat()
3081 throws RemoteException {
3082 final NotificationRecord r = generateNotificationRecord(
3083 mTestNotificationChannel, 1, null, true);
3084 r.setTextChanged(true);
3085 mService.addNotification(r);
3086
3087 mBinderService.setNotificationsShownFromListener(null, new String[] {r.getKey()});
3088
3089 verify(mAppUsageStats).reportInterruptiveNotification(anyString(), anyString(), anyInt());
3090 }
3091
3092 @Test
3093 public void testMybeRecordInterruptionLocked_doesNotRecordTwice()
3094 throws RemoteException {
3095 final NotificationRecord r = generateNotificationRecord(
3096 mTestNotificationChannel, 1, null, true);
3097 r.setInterruptive(true);
3098 mService.addNotification(r);
3099
3100 mService.maybeRecordInterruptionLocked(r);
3101 mService.maybeRecordInterruptionLocked(r);
3102
3103 verify(mAppUsageStats, times(1)).reportInterruptiveNotification(
3104 anyString(), anyString(), anyInt());
3105 }
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -05003106}