blob: 31788ae9b194100fd7b2674818508064a6383ee2 [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
Beverly58b24532018-10-02 09:08:23 -040019import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
20import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
Julia Reynoldse5c60452018-04-30 14:41:36 -040021import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -050022import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
Julia Reynolds27c0a962018-12-10 12:37:28 -050023import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040024import static android.app.NotificationManager.IMPORTANCE_HIGH;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040025import static android.app.NotificationManager.IMPORTANCE_LOW;
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -050026import static android.app.NotificationManager.IMPORTANCE_MAX;
Julia Reynolds4da79702017-06-01 11:06:10 -040027import static android.app.NotificationManager.IMPORTANCE_NONE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040028import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -050029import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
30import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
31import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
32import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
33import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
34import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
35import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
36import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
37import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
Julia Reynoldse1816412017-10-24 10:39:11 -040038import static android.content.pm.PackageManager.FEATURE_WATCH;
Julia Reynolds4db59552017-06-30 13:34:01 -040039import static android.content.pm.PackageManager.PERMISSION_DENIED;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -050040import static android.os.Build.VERSION_CODES.O_MR1;
41import static android.os.Build.VERSION_CODES.P;
Tony Makeda84a72018-11-19 17:01:32 +000042import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
43import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040044
Geoffrey Pitsch03533712017-01-05 10:30:07 -050045import static junit.framework.Assert.assertEquals;
Julia Reynolds727a7282017-04-13 10:54:01 -040046import static junit.framework.Assert.assertFalse;
Julia Reynolds92febc32017-10-26 11:30:31 -040047import static junit.framework.Assert.assertNotNull;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040048import static junit.framework.Assert.assertNull;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050049import static junit.framework.Assert.assertTrue;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050050import static junit.framework.Assert.fail;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050051
Julia Reynolds5f20e9f2017-01-30 08:54:53 -050052import static org.mockito.Matchers.anyBoolean;
Julia Reynoldsa78cdff2017-04-26 10:19:25 -040053import static org.mockito.Matchers.anyLong;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050054import static org.mockito.Matchers.anyString;
55import static org.mockito.Matchers.eq;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050056import static org.mockito.Mockito.any;
57import static org.mockito.Mockito.anyInt;
Julia Reynoldseb3dca72017-07-11 10:39:58 -040058import static org.mockito.Mockito.doAnswer;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050059import static org.mockito.Mockito.mock;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040060import static org.mockito.Mockito.never;
61import static org.mockito.Mockito.reset;
Julia Reynolds503ed942017-10-04 16:04:56 -040062import static org.mockito.Mockito.spy;
63import static org.mockito.Mockito.timeout;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050064import static org.mockito.Mockito.times;
65import static org.mockito.Mockito.verify;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050066import static org.mockito.Mockito.when;
67
Julia Reynolds68263d12017-06-21 14:21:19 -040068import android.app.ActivityManager;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -040069import android.app.AppOpsManager;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040070import android.app.IActivityManager;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050071import android.app.INotificationManager;
Julia Reynolds268647a2018-10-25 16:54:27 -040072import android.app.ITransientNotification;
73import android.app.IUriGrantsManager;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050074import android.app.Notification;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040075import android.app.Notification.MessagingStyle.Message;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050076import android.app.NotificationChannel;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040077import android.app.NotificationChannelGroup;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050078import android.app.NotificationManager;
Jason Parks50322ff2018-03-27 10:23:33 -050079import android.app.admin.DevicePolicyManagerInternal;
Julia Reynolds7217dc92018-03-07 12:12:09 -050080import android.app.usage.UsageStatsManagerInternal;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040081import android.companion.ICompanionDeviceManager;
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -050082import android.content.ComponentName;
Jeff Sharkey6a97cc32018-04-17 12:16:20 -060083import android.content.ContentUris;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050084import android.content.Context;
Beverlyd4f96492017-08-02 13:36:11 -040085import android.content.Intent;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050086import android.content.pm.ApplicationInfo;
87import android.content.pm.IPackageManager;
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -050088import android.content.pm.PackageManager;
Geoffrey Pitsch03533712017-01-05 10:30:07 -050089import android.content.pm.ParceledListSlice;
Kristian Monsen05f34792018-04-09 10:27:16 +020090import android.content.res.Resources;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040091import android.graphics.Color;
Julia Reynolds76c096d2017-06-19 08:16:04 -040092import android.media.AudioManager;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040093import android.net.Uri;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050094import android.os.Binder;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040095import android.os.Build;
Julia Reynolds503ed942017-10-04 16:04:56 -040096import android.os.Bundle;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040097import android.os.IBinder;
Julia Reynoldsf27d6b22017-04-13 15:48:16 -040098import android.os.Process;
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -040099import android.os.RemoteException;
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500100import android.os.UserHandle;
Jeff Sharkey6a97cc32018-04-17 12:16:20 -0600101import android.provider.MediaStore;
Julia Reynolds503ed942017-10-04 16:04:56 -0400102import android.service.notification.Adjustment;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400103import android.service.notification.NotificationListenerService;
Julia Reynolds503ed942017-10-04 16:04:56 -0400104import android.service.notification.NotificationStats;
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500105import android.service.notification.NotifyingApp;
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500106import android.service.notification.StatusBarNotification;
Geoffrey Pitsch8185d382017-05-19 18:41:32 -0400107import android.test.suitebuilder.annotation.SmallTest;
Jason Monk745d0a82017-04-17 11:34:22 -0400108import android.testing.AndroidTestingRunner;
Julia Reynolds92febc32017-10-26 11:30:31 -0400109import android.testing.TestableContext;
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400110import android.testing.TestableLooper;
Jason Monk745d0a82017-04-17 11:34:22 -0400111import android.testing.TestableLooper.RunWithLooper;
Dan Sandler7d67bd42018-05-15 14:06:38 -0400112import android.text.Html;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400113import android.util.ArrayMap;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400114import android.util.AtomicFile;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400115
Kristian Monsen05f34792018-04-09 10:27:16 +0200116import com.android.internal.R;
Julia Reynolds503ed942017-10-04 16:04:56 -0400117import com.android.internal.statusbar.NotificationVisibility;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700118import com.android.server.LocalServices;
Beverly58b24532018-10-02 09:08:23 -0400119import com.android.server.SystemService;
Jason Monk74f5e362017-12-06 08:56:33 -0500120import com.android.server.UiServiceTestCase;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400121import com.android.server.lights.Light;
122import com.android.server.lights.LightsManager;
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400123import com.android.server.notification.NotificationManagerService.NotificationAssistants;
124import com.android.server.notification.NotificationManagerService.NotificationListeners;
Annie Meng8b646fd2019-02-01 18:46:42 +0000125import com.android.server.pm.UserManagerService;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700126import com.android.server.uri.UriGrantsManagerInternal;
Beverly58b24532018-10-02 09:08:23 -0400127import com.android.server.wm.WindowManagerInternal;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400128
129import org.junit.After;
130import org.junit.Before;
131import org.junit.Test;
132import org.junit.runner.RunWith;
Julia Reynolds40f00d72017-12-12 10:47:32 -0500133import org.mockito.ArgumentCaptor;
134import org.mockito.Mock;
135import org.mockito.MockitoAnnotations;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400136import org.mockito.stubbing.Answer;
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500137
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400138import java.io.BufferedInputStream;
139import java.io.ByteArrayInputStream;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400140import java.io.File;
141import java.io.FileInputStream;
142import java.io.FileOutputStream;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400143import java.util.ArrayList;
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500144import java.util.Arrays;
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500145import java.util.HashSet;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400146import java.util.List;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400147import java.util.Map;
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500148import java.util.Set;
Robin Leed107af62018-04-27 13:55:56 +0200149import java.util.function.Consumer;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500150
Geoffrey Pitsch8185d382017-05-19 18:41:32 -0400151@SmallTest
Jason Monk745d0a82017-04-17 11:34:22 -0400152@RunWith(AndroidTestingRunner.class)
153@RunWithLooper
Jason Monk74f5e362017-12-06 08:56:33 -0500154public class NotificationManagerServiceTest extends UiServiceTestCase {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500155 private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400156 private final int mUid = Binder.getCallingUid();
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500157 private TestableNotificationManagerService mService;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500158 private INotificationManager mBinderService;
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400159 private NotificationManagerInternal mInternalService;
Julia Reynoldsda781472017-04-12 09:41:16 -0400160 @Mock
161 private IPackageManager mPackageManager;
162 @Mock
163 private PackageManager mPackageManagerClient;
Beverly58b24532018-10-02 09:08:23 -0400164 @Mock
165 private WindowManagerInternal mWindowManagerInternal;
Julia Reynolds92febc32017-10-26 11:30:31 -0400166 private TestableContext mContext = spy(getContext());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500167 private final String PKG = mContext.getPackageName();
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400168 private TestableLooper mTestableLooper;
Julia Reynoldsda781472017-04-12 09:41:16 -0400169 @Mock
170 private RankingHelper mRankingHelper;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400171 @Mock private PreferencesHelper mPreferencesHelper;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400172 AtomicFile mPolicyFile;
173 File mFile;
174 @Mock
Geoffrey Pitschd5bcf212017-06-01 15:45:35 -0400175 private NotificationUsageStats mUsageStats;
Julia Reynolds76c096d2017-06-19 08:16:04 -0400176 @Mock
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -0400177 private UsageStatsManagerInternal mAppUsageStats;
178 @Mock
Julia Reynolds76c096d2017-06-19 08:16:04 -0400179 private AudioManager mAudioManager;
Julia Reynolds68263d12017-06-21 14:21:19 -0400180 @Mock
181 ActivityManager mActivityManager;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400182 NotificationManagerService.WorkerHandler mHandler;
Kristian Monsen05f34792018-04-09 10:27:16 +0200183 @Mock
184 Resources mResources;
Julia Reynolds3ff26d22017-06-19 08:16:04 -0400185
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500186 private NotificationChannel mTestNotificationChannel = new NotificationChannel(
Julia Reynolds27c0a962018-12-10 12:37:28 -0500187 TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
Gustav Senntona8e38aa2019-01-22 14:55:39 +0000188
189 private static final int NOTIFICATION_LOCATION_UNKNOWN = 0;
190
Julia Reynoldsda781472017-04-12 09:41:16 -0400191 @Mock
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400192 private NotificationListeners mListeners;
193 @Mock private NotificationAssistants mAssistants;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400194 @Mock private ConditionProviders mConditionProviders;
Julia Reynoldsda781472017-04-12 09:41:16 -0400195 private ManagedServices.ManagedServiceInfo mListener;
196 @Mock private ICompanionDeviceManager mCompanionMgr;
Julia Reynoldsa78cdff2017-04-26 10:19:25 -0400197 @Mock SnoozeHelper mSnoozeHelper;
Julia Reynolds8aebf352017-06-26 11:35:33 -0400198 @Mock GroupHelper mGroupHelper;
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400199 @Mock
200 IBinder mPermOwner;
201 @Mock
202 IActivityManager mAm;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700203 @Mock
204 IUriGrantsManager mUgm;
205 @Mock
206 UriGrantsManagerInternal mUgmInternal;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400207 @Mock
208 AppOpsManager mAppOpsManager;
Annie Meng8b646fd2019-02-01 18:46:42 +0000209 @Mock
210 private UserManagerService mUserMangerService;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500211
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400212 // Use a Testable subclass so we can simulate calls from the system without failing.
213 private static class TestableNotificationManagerService extends NotificationManagerService {
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500214 int countSystemChecks = 0;
Brad Stenning8c991ea2018-07-31 13:33:01 -0700215 boolean isSystemUid = true;
Gustav Sennton44dc5882018-12-13 14:38:50 +0000216 int countLogSmartSuggestionsVisible = 0;
Annie Meng8b646fd2019-02-01 18:46:42 +0000217 UserManagerService mUserManagerService;
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500218
Annie Meng8b646fd2019-02-01 18:46:42 +0000219 TestableNotificationManagerService(Context context, UserManagerService userManagerService) {
Amith Yamasani803eab692017-11-09 17:47:04 -0800220 super(context);
Annie Meng8b646fd2019-02-01 18:46:42 +0000221 mUserManagerService = userManagerService;
Amith Yamasani803eab692017-11-09 17:47:04 -0800222 }
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400223
224 @Override
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400225 protected boolean isCallingUidSystem() {
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500226 countSystemChecks++;
Brad Stenning8c991ea2018-07-31 13:33:01 -0700227 return isSystemUid;
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400228 }
229
230 @Override
231 protected boolean isCallerSystemOrPhone() {
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500232 countSystemChecks++;
Brad Stenning8c991ea2018-07-31 13:33:01 -0700233 return isSystemUid;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400234 }
Julia Reynolds727a7282017-04-13 10:54:01 -0400235
236 @Override
237 protected ICompanionDeviceManager getCompanionManager() {
238 return null;
239 }
Amith Yamasani803eab692017-11-09 17:47:04 -0800240
241 @Override
Amith Yamasani7ec89412018-02-07 08:48:49 -0800242 protected void reportUserInteraction(NotificationRecord r) {
243 return;
244 }
Julia Reynoldsb62dad42018-11-26 16:33:02 -0500245
246 @Override
247 protected void handleSavePolicyFile() {
248 return;
249 }
Gustav Sennton44dc5882018-12-13 14:38:50 +0000250
251 @Override
Gustav Senntonc7d0d322019-01-07 15:36:41 +0000252 void logSmartSuggestionsVisible(NotificationRecord r, int notificationLocation) {
253 super.logSmartSuggestionsVisible(r, notificationLocation);
Gustav Sennton44dc5882018-12-13 14:38:50 +0000254 countLogSmartSuggestionsVisible++;
255 }
256
Annie Meng8b646fd2019-02-01 18:46:42 +0000257 @Override
258 UserManagerService getUserManagerService() {
259 return mUserManagerService;
260 }
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400261 }
262
Beverly58b24532018-10-02 09:08:23 -0400263 private class TestableToastCallback extends ITransientNotification.Stub {
264 @Override
265 public void show(IBinder windowToken) {
266 }
267
268 @Override
269 public void hide() {
270 }
271 }
272
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500273 @Before
274 public void setUp() throws Exception {
Julia Reynoldsda781472017-04-12 09:41:16 -0400275 MockitoAnnotations.initMocks(this);
Chris Wren89aa2262017-05-05 18:05:56 -0400276
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700277 LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
278 LocalServices.addService(UriGrantsManagerInternal.class, mUgmInternal);
Beverly58b24532018-10-02 09:08:23 -0400279 LocalServices.removeServiceForTest(WindowManagerInternal.class);
280 LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700281
Annie Meng8b646fd2019-02-01 18:46:42 +0000282 mService = new TestableNotificationManagerService(mContext, mUserMangerService);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500283
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400284 // Use this testable looper.
285 mTestableLooper = TestableLooper.get(this);
Julia Reynolds503ed942017-10-04 16:04:56 -0400286 mHandler = mService.new WorkerHandler(mTestableLooper.getLooper());
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500287 // MockPackageManager - default returns ApplicationInfo with matching calling UID
Julia Reynolds92febc32017-10-26 11:30:31 -0400288 mContext.setMockPackageManager(mPackageManagerClient);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500289 final ApplicationInfo applicationInfo = new ApplicationInfo();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400290 applicationInfo.uid = mUid;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400291 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500292 .thenReturn(applicationInfo);
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500293 when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500294 .thenReturn(applicationInfo);
Julia Reynolds92febc32017-10-26 11:30:31 -0400295 when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid);
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500296 final LightsManager mockLightsManager = mock(LightsManager.class);
297 when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
Julia Reynolds76c096d2017-06-19 08:16:04 -0400298 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
Julia Reynoldse1816412017-10-24 10:39:11 -0400299 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700300 when(mUgmInternal.newUriPermissionOwner(anyString())).thenReturn(mPermOwner);
Julia Reynolds268647a2018-10-25 16:54:27 -0400301 when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500302
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400303 // write to a test file; the system file isn't readable from tests
Julia Reynoldsb852e562017-06-06 16:14:18 -0400304 mFile = new File(mContext.getCacheDir(), "test.xml");
305 mFile.createNewFile();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400306 final String preupgradeXml = "<notification-policy></notification-policy>";
307 mPolicyFile = new AtomicFile(mFile);
308 FileOutputStream fos = mPolicyFile.startWrite();
309 fos.write(preupgradeXml.getBytes());
310 mPolicyFile.finishWrite(fos);
311 FileInputStream fStream = new FileInputStream(mFile);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400312
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400313 // Setup managed services
314 mListener = mListeners.new ManagedServiceInfo(
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400315 null, new ComponentName(PKG, "test_class"), mUid, true, null, 0);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400316 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
317 ManagedServices.Config listenerConfig = new ManagedServices.Config();
318 listenerConfig.xmlTag = NotificationListeners.TAG_ENABLED_NOTIFICATION_LISTENERS;
319 when(mListeners.getConfig()).thenReturn(listenerConfig);
320 ManagedServices.Config assistantConfig = new ManagedServices.Config();
321 assistantConfig.xmlTag = NotificationAssistants.TAG_ENABLED_NOTIFICATION_ASSISTANTS;
322 when(mAssistants.getConfig()).thenReturn(assistantConfig);
323 ManagedServices.Config dndConfig = new ManagedServices.Config();
324 dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS;
325 when(mConditionProviders.getConfig()).thenReturn(dndConfig);
326
Julia Reynoldsb852e562017-06-06 16:14:18 -0400327 try {
Julia Reynolds503ed942017-10-04 16:04:56 -0400328 mService.init(mTestableLooper.getLooper(),
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400329 mPackageManager, mPackageManagerClient, mockLightsManager,
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400330 mListeners, mAssistants, mConditionProviders,
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400331 mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -0400332 mGroupHelper, mAm, mAppUsageStats,
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400333 mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal,
334 mAppOpsManager);
Beverly58b24532018-10-02 09:08:23 -0400335 mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400336 } catch (SecurityException e) {
337 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
338 throw e;
339 }
340 }
Julia Reynolds503ed942017-10-04 16:04:56 -0400341 mService.setAudioManager(mAudioManager);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500342
343 // Tests call directly into the Binder.
Julia Reynolds503ed942017-10-04 16:04:56 -0400344 mBinderService = mService.getBinderService();
345 mInternalService = mService.getInternalService();
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500346
347 mBinderService.createNotificationChannels(
348 PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel)));
Julia Reynolds92febc32017-10-26 11:30:31 -0400349 assertNotNull(mBinderService.getNotificationChannel(PKG, TEST_CHANNEL_ID));
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500350 }
351
Julia Reynoldsb852e562017-06-06 16:14:18 -0400352 @After
353 public void tearDown() throws Exception {
354 mFile.delete();
355 }
356
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500357 public void waitForIdle() {
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400358 mTestableLooper.processAllMessages();
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500359 }
360
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500361 private StatusBarNotification generateSbn(String pkg, int uid, long postTime, int userId) {
362 Notification.Builder nb = new Notification.Builder(mContext, "a")
363 .setContentTitle("foo")
364 .setSmallIcon(android.R.drawable.sym_def_app_icon);
365 StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, uid, "tag", uid, 0,
366 nb.build(), new UserHandle(userId), null, postTime);
367 return sbn;
368 }
369
Julia Reynoldsa78cdff2017-04-26 10:19:25 -0400370 private NotificationRecord generateNotificationRecord(NotificationChannel channel, int id,
371 String groupKey, boolean isSummary) {
372 Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
373 .setContentTitle("foo")
374 .setSmallIcon(android.R.drawable.sym_def_app_icon)
375 .setGroup(groupKey)
376 .setGroupSummary(isSummary);
377
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400378 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
379 nb.build(), new UserHandle(mUid), null, 0);
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000380 return new NotificationRecord(mContext, sbn, channel);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -0400381 }
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400382
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500383 private NotificationRecord generateNotificationRecord(NotificationChannel channel) {
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500384 return generateNotificationRecord(channel, null);
385 }
386
387 private NotificationRecord generateNotificationRecord(NotificationChannel channel,
388 Notification.TvExtender extender) {
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500389 if (channel == null) {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500390 channel = mTestNotificationChannel;
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500391 }
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500392 Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500393 .setContentTitle("foo")
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500394 .setSmallIcon(android.R.drawable.sym_def_app_icon);
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500395 if (extender != null) {
396 nb.extend(extender);
397 }
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400398 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
399 nb.build(), new UserHandle(mUid), null, 0);
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000400 return new NotificationRecord(mContext, sbn, channel);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500401 }
402
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400403 private Map<String, Answer> getSignalExtractorSideEffects() {
404 Map<String, Answer> answers = new ArrayMap<>();
405
406 answers.put("override group key", invocationOnMock -> {
407 ((NotificationRecord) invocationOnMock.getArguments()[0])
408 .setOverrideGroupKey("bananas");
409 return null;
410 });
411 answers.put("override people", invocationOnMock -> {
412 ((NotificationRecord) invocationOnMock.getArguments()[0])
413 .setPeopleOverride(new ArrayList<>());
414 return null;
415 });
416 answers.put("snooze criteria", invocationOnMock -> {
417 ((NotificationRecord) invocationOnMock.getArguments()[0])
418 .setSnoozeCriteria(new ArrayList<>());
419 return null;
420 });
421 answers.put("notification channel", invocationOnMock -> {
422 ((NotificationRecord) invocationOnMock.getArguments()[0])
423 .updateNotificationChannel(new NotificationChannel("a", "", IMPORTANCE_LOW));
424 return null;
425 });
426 answers.put("badging", invocationOnMock -> {
427 NotificationRecord r = (NotificationRecord) invocationOnMock.getArguments()[0];
428 r.setShowBadge(!r.canShowBadge());
429 return null;
430 });
Julia Reynolds4509ce72019-01-31 13:12:43 -0500431 answers.put("bubbles", invocationOnMock -> {
432 NotificationRecord r = (NotificationRecord) invocationOnMock.getArguments()[0];
433 r.setAllowBubble(!r.canBubble());
434 return null;
435 });
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400436 answers.put("package visibility", invocationOnMock -> {
437 ((NotificationRecord) invocationOnMock.getArguments()[0]).setPackageVisibilityOverride(
438 Notification.VISIBILITY_SECRET);
439 return null;
440 });
441
442 return answers;
443 }
444
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500445 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500446 public void testCreateNotificationChannels_SingleChannel() throws Exception {
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500447 final NotificationChannel channel =
Julia Reynolds27c0a962018-12-10 12:37:28 -0500448 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400449 mBinderService.createNotificationChannels(PKG,
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500450 new ParceledListSlice(Arrays.asList(channel)));
451 final NotificationChannel createdChannel =
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400452 mBinderService.getNotificationChannel(PKG, "id");
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500453 assertTrue(createdChannel != null);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500454 }
455
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500456 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500457 public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception {
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500458 try {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400459 mBinderService.createNotificationChannels(PKG,
Kristian Monsen05f34792018-04-09 10:27:16 +0200460 new ParceledListSlice(Arrays.asList((Object[])null)));
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500461 fail("Exception should be thrown immediately.");
462 } catch (NullPointerException e) {
463 // pass
464 }
465 }
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500466
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500467 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500468 public void testCreateNotificationChannels_TwoChannels() throws Exception {
469 final NotificationChannel channel1 =
Julia Reynolds27c0a962018-12-10 12:37:28 -0500470 new NotificationChannel("id1", "name", IMPORTANCE_DEFAULT);
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500471 final NotificationChannel channel2 =
Julia Reynolds27c0a962018-12-10 12:37:28 -0500472 new NotificationChannel("id2", "name", IMPORTANCE_DEFAULT);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400473 mBinderService.createNotificationChannels(PKG,
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500474 new ParceledListSlice(Arrays.asList(channel1, channel2)));
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400475 assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null);
476 assertTrue(mBinderService.getNotificationChannel(PKG, "id2") != null);
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500477 }
478
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500479 @Test
Geoffrey Pitsch76a3aa02017-07-26 15:07:34 -0400480 public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance()
481 throws Exception {
482 final NotificationChannel channel =
Julia Reynolds27c0a962018-12-10 12:37:28 -0500483 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
Geoffrey Pitsch76a3aa02017-07-26 15:07:34 -0400484 mBinderService.createNotificationChannels(PKG,
485 new ParceledListSlice(Arrays.asList(channel)));
486
487 // Recreating the channel doesn't throw, but ignores importance.
488 final NotificationChannel dupeChannel =
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400489 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
Geoffrey Pitsch76a3aa02017-07-26 15:07:34 -0400490 mBinderService.createNotificationChannels(PKG,
491 new ParceledListSlice(Arrays.asList(dupeChannel)));
492 final NotificationChannel createdChannel =
493 mBinderService.getNotificationChannel(PKG, "id");
Julia Reynolds27c0a962018-12-10 12:37:28 -0500494 assertEquals(IMPORTANCE_DEFAULT, createdChannel.getImportance());
Geoffrey Pitsch76a3aa02017-07-26 15:07:34 -0400495 }
496
497 @Test
498 public void testCreateNotificationChannels_SecondCreateAllowedToDowngradeImportance()
499 throws Exception {
500 final NotificationChannel channel =
Julia Reynolds27c0a962018-12-10 12:37:28 -0500501 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
Geoffrey Pitsch76a3aa02017-07-26 15:07:34 -0400502 mBinderService.createNotificationChannels(PKG,
503 new ParceledListSlice(Arrays.asList(channel)));
504
505 // Recreating with a lower importance is allowed to modify the channel.
506 final NotificationChannel dupeChannel =
507 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
508 mBinderService.createNotificationChannels(PKG,
509 new ParceledListSlice(Arrays.asList(dupeChannel)));
510 final NotificationChannel createdChannel =
511 mBinderService.getNotificationChannel(PKG, "id");
512 assertEquals(NotificationManager.IMPORTANCE_LOW, createdChannel.getImportance());
513 }
514
515 @Test
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400516 public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated()
517 throws Exception {
518 final NotificationChannel channel =
Julia Reynolds27c0a962018-12-10 12:37:28 -0500519 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400520 mBinderService.createNotificationChannels(PKG,
521 new ParceledListSlice(Arrays.asList(channel)));
522
523 // The user modifies importance directly, can no longer be changed by the app.
524 final NotificationChannel updatedChannel =
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400525 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400526 mBinderService.updateNotificationChannelForPackage(PKG, mUid, updatedChannel);
527
528 // Recreating with a lower importance leaves channel unchanged.
529 final NotificationChannel dupeChannel =
530 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
531 mBinderService.createNotificationChannels(PKG,
532 new ParceledListSlice(Arrays.asList(dupeChannel)));
533 final NotificationChannel createdChannel =
534 mBinderService.getNotificationChannel(PKG, "id");
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400535 assertEquals(IMPORTANCE_HIGH, createdChannel.getImportance());
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400536 }
537
538 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500539 public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond()
540 throws Exception {
541 final NotificationChannel channel1 =
Julia Reynolds27c0a962018-12-10 12:37:28 -0500542 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500543 final NotificationChannel channel2 =
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400544 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400545 mBinderService.createNotificationChannels(PKG,
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500546 new ParceledListSlice(Arrays.asList(channel1, channel2)));
547 final NotificationChannel createdChannel =
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400548 mBinderService.getNotificationChannel(PKG, "id");
Julia Reynolds27c0a962018-12-10 12:37:28 -0500549 assertEquals(IMPORTANCE_DEFAULT, createdChannel.getImportance());
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500550 }
551
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500552 @Test
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500553 public void testBlockedNotifications_suspended() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500554 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(true);
555
556 NotificationChannel channel = new NotificationChannel("id", "name",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400557 IMPORTANCE_HIGH);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500558 NotificationRecord r = generateNotificationRecord(channel);
Beverly3c707b42018-09-14 09:49:07 -0400559
560 // isBlocked is only used for user blocking, not app suspension
561 assertFalse(mService.isBlocked(r, mUsageStats));
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500562 }
563
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500564 @Test
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500565 public void testBlockedNotifications_blockedChannel() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500566 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
567
568 NotificationChannel channel = new NotificationChannel("id", "name",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400569 NotificationManager.IMPORTANCE_NONE);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500570 NotificationRecord r = generateNotificationRecord(channel);
Julia Reynolds503ed942017-10-04 16:04:56 -0400571 assertTrue(mService.isBlocked(r, mUsageStats));
Geoffrey Pitschd5bcf212017-06-01 15:45:35 -0400572 verify(mUsageStats, times(1)).registerBlocked(eq(r));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400573
574 mBinderService.createNotificationChannels(
575 PKG, new ParceledListSlice(Arrays.asList(channel)));
576 final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400577 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400578 sbn.getId(), sbn.getNotification(), sbn.getUserId());
579 waitForIdle();
580 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
581 }
582
583 @Test
584 public void testEnqueuedBlockedNotifications_appBlockedChannelForegroundService()
585 throws Exception {
586 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
587
588 NotificationChannel channel = new NotificationChannel("blocked", "name",
589 NotificationManager.IMPORTANCE_NONE);
590 mBinderService.createNotificationChannels(
591 PKG, new ParceledListSlice(Arrays.asList(channel)));
592
593 final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400594 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400595 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400596 sbn.getId(), sbn.getNotification(), sbn.getUserId());
597 waitForIdle();
598 assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
599 assertEquals(IMPORTANCE_LOW,
Julia Reynolds503ed942017-10-04 16:04:56 -0400600 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400601 assertEquals(IMPORTANCE_LOW,
602 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
603 }
604
605 @Test
606 public void testEnqueuedBlockedNotifications_userBlockedChannelForegroundService()
607 throws Exception {
608 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
609
610 NotificationChannel channel =
611 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_HIGH);
612 mBinderService.createNotificationChannels(
613 PKG, new ParceledListSlice(Arrays.asList(channel)));
614
615 NotificationChannel update =
616 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
617 mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
618 waitForIdle();
619 assertEquals(IMPORTANCE_NONE,
620 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
621
Dianne Hackborn025d4a52018-04-30 16:23:26 -0700622 StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400623 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400624 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400625 sbn.getId(), sbn.getNotification(), sbn.getUserId());
626 waitForIdle();
Dianne Hackborn025d4a52018-04-30 16:23:26 -0700627 // The first time a foreground service notification is shown, we allow the channel
628 // to be updated to allow it to be seen.
629 assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
630 assertEquals(IMPORTANCE_LOW,
631 mService.getNotificationRecord(sbn.getKey()).getImportance());
632 assertEquals(IMPORTANCE_LOW,
633 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
634 mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
635 waitForIdle();
636
637 update = new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
638 update.setFgServiceShown(true);
639 mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
640 waitForIdle();
641 assertEquals(IMPORTANCE_NONE,
642 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
643
644 sbn = generateNotificationRecord(channel).sbn;
645 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400646 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Dianne Hackborn025d4a52018-04-30 16:23:26 -0700647 sbn.getId(), sbn.getNotification(), sbn.getUserId());
648 waitForIdle();
649 // The second time it is shown, we keep the user's preference.
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400650 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400651 assertNull(mService.getNotificationRecord(sbn.getKey()));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400652 assertEquals(IMPORTANCE_NONE,
653 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500654 }
655
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500656 @Test
Julia Reynolds005c8b92017-08-24 10:35:53 -0400657 public void testBlockedNotifications_blockedChannelGroup() throws Exception {
658 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400659 mService.setPreferencesHelper(mPreferencesHelper);
660 when(mPreferencesHelper.isGroupBlocked(anyString(), anyInt(), anyString())).thenReturn(true);
Julia Reynolds005c8b92017-08-24 10:35:53 -0400661
662 NotificationChannel channel = new NotificationChannel("id", "name",
663 NotificationManager.IMPORTANCE_HIGH);
664 channel.setGroup("something");
665 NotificationRecord r = generateNotificationRecord(channel);
Julia Reynolds503ed942017-10-04 16:04:56 -0400666 assertTrue(mService.isBlocked(r, mUsageStats));
Julia Reynolds005c8b92017-08-24 10:35:53 -0400667 verify(mUsageStats, times(1)).registerBlocked(eq(r));
668 }
669
670 @Test
Julia Reynolds4da79702017-06-01 11:06:10 -0400671 public void testEnqueuedBlockedNotifications_blockedApp() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500672 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
673
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400674 mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
Julia Reynolds4da79702017-06-01 11:06:10 -0400675
676 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400677 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds4da79702017-06-01 11:06:10 -0400678 sbn.getId(), sbn.getNotification(), sbn.getUserId());
679 waitForIdle();
680 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500681 }
682
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500683 @Test
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400684 public void testEnqueuedBlockedNotifications_blockedAppForegroundService() throws Exception {
685 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
686
687 mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
688
689 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400690 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400691 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400692 sbn.getId(), sbn.getNotification(), sbn.getUserId());
693 waitForIdle();
694 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400695 assertNull(mService.getNotificationRecord(sbn.getKey()));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400696 }
697
Brad Stenning8c991ea2018-07-31 13:33:01 -0700698 /**
699 * Confirm the system user on automotive devices can use car categories
700 */
701 @Test
702 public void testEnqueuedRestrictedNotifications_asSystem() throws Exception {
703 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
704 .thenReturn(true);
705 List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
706 Notification.CATEGORY_CAR_WARNING,
707 Notification.CATEGORY_CAR_INFORMATION);
708 int id = 0;
709 for (String category: categories) {
710 final StatusBarNotification sbn =
711 generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
712 sbn.getNotification().category = category;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400713 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Brad Stenning8c991ea2018-07-31 13:33:01 -0700714 sbn.getId(), sbn.getNotification(), sbn.getUserId());
715 }
716 waitForIdle();
717 assertEquals(categories.size(), mBinderService.getActiveNotifications(PKG).length);
718 }
719
720
721 /**
722 * Confirm restricted notification categories only apply to automotive.
723 */
724 @Test
725 public void testEnqueuedRestrictedNotifications_notAutomotive() throws Exception {
726 mService.isSystemUid = false;
727 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
728 .thenReturn(false);
729 List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
730 Notification.CATEGORY_CAR_WARNING,
731 Notification.CATEGORY_CAR_INFORMATION);
732 int id = 0;
733 for (String category: categories) {
734 final StatusBarNotification sbn =
735 generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
736 sbn.getNotification().category = category;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400737 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Brad Stenning8c991ea2018-07-31 13:33:01 -0700738 sbn.getId(), sbn.getNotification(), sbn.getUserId());
739 }
740 waitForIdle();
741 assertEquals(categories.size(), mBinderService.getActiveNotifications(PKG).length);
742 }
743
744 /**
745 * Confirm if a non-system user tries to use the car categories on a automotive device that
746 * they will get a security exception
747 */
748 @Test
749 public void testEnqueuedRestrictedNotifications_badUser() throws Exception {
750 mService.isSystemUid = false;
751 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
752 .thenReturn(true);
753 List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
754 Notification.CATEGORY_CAR_WARNING,
755 Notification.CATEGORY_CAR_INFORMATION);
756 for (String category: categories) {
757 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
758 sbn.getNotification().category = category;
759 try {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400760 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Brad Stenning8c991ea2018-07-31 13:33:01 -0700761 sbn.getId(), sbn.getNotification(), sbn.getUserId());
762 fail("Calls from non system apps should not allow use of restricted categories");
763 } catch (SecurityException e) {
764 // pass
765 }
766 }
767 waitForIdle();
768 assertEquals(0, mBinderService.getActiveNotifications(PKG).length);
769 }
770
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400771 @Test
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400772 public void testBlockedNotifications_blockedByAssistant() throws Exception {
773 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
Julia Reynolds27c0a962018-12-10 12:37:28 -0500774 when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400775
776 NotificationChannel channel = new NotificationChannel("id", "name",
777 NotificationManager.IMPORTANCE_HIGH);
778 NotificationRecord r = generateNotificationRecord(channel);
779 mService.addEnqueuedNotification(r);
780
Julia Reynolds27c0a962018-12-10 12:37:28 -0500781 Bundle bundle = new Bundle();
782 bundle.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE);
783 Adjustment adjustment = new Adjustment(
784 r.sbn.getPackageName(), r.getKey(), bundle, "", r.getUser().getIdentifier());
785 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400786
787 NotificationManagerService.PostNotificationRunnable runnable =
788 mService.new PostNotificationRunnable(r.getKey());
789 runnable.run();
790 waitForIdle();
791
792 verify(mUsageStats, never()).registerPostedByApp(any());
793 }
794
795 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500796 public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400797 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400798 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500799 waitForIdle();
Julia Reynolds080361e2017-07-13 11:23:12 -0400800 StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500801 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400802 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500803 }
804
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500805 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500806 public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400807 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400808 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500809 mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500810 waitForIdle();
811 StatusBarNotification[] notifs =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500812 mBinderService.getActiveNotifications(PKG);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500813 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400814 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500815 }
816
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500817 @Test
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500818 public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400819 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400820 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500821 waitForIdle();
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400822 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400823 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500824 mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500825 waitForIdle();
826 StatusBarNotification[] notifs =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500827 mBinderService.getActiveNotifications(PKG);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500828 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400829 assertEquals(0, mService.getNotificationRecordCount());
830 ArgumentCaptor<NotificationStats> captor = ArgumentCaptor.forClass(NotificationStats.class);
831 verify(mListeners, times(1)).notifyRemovedLocked(any(), anyInt(), captor.capture());
832 assertEquals(NotificationStats.DISMISSAL_OTHER, captor.getValue().getDismissalSurface());
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500833 }
834
835 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500836 public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -0400837 NotificationRecord r = generateNotificationRecord(null);
838 final StatusBarNotification sbn = r.sbn;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400839 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400840 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500841 mBinderService.cancelNotificationsFromListener(null, null);
842 waitForIdle();
843 StatusBarNotification[] notifs =
844 mBinderService.getActiveNotifications(sbn.getPackageName());
845 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400846 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500847 }
848
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500849 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500850 public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
851 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400852 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400853 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500854 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500855 waitForIdle();
856 StatusBarNotification[] notifs =
857 mBinderService.getActiveNotifications(sbn.getPackageName());
858 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400859 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds080361e2017-07-13 11:23:12 -0400860 }
861
862 @Test
863 public void testUserInitiatedClearAll_noLeak() throws Exception {
864 final NotificationRecord n = generateNotificationRecord(
865 mTestNotificationChannel, 1, "group", true);
866
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400867 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds080361e2017-07-13 11:23:12 -0400868 n.sbn.getId(), n.sbn.getNotification(), n.sbn.getUserId());
869 waitForIdle();
870
Julia Reynolds503ed942017-10-04 16:04:56 -0400871 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Julia Reynolds080361e2017-07-13 11:23:12 -0400872 n.getUserId());
873 waitForIdle();
874 StatusBarNotification[] notifs =
875 mBinderService.getActiveNotifications(n.sbn.getPackageName());
876 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400877 assertEquals(0, mService.getNotificationRecordCount());
878 ArgumentCaptor<NotificationStats> captor = ArgumentCaptor.forClass(NotificationStats.class);
879 verify(mListeners, times(1)).notifyRemovedLocked(any(), anyInt(), captor.capture());
880 assertEquals(NotificationStats.DISMISSAL_OTHER, captor.getValue().getDismissalSurface());
Julia Reynolds080361e2017-07-13 11:23:12 -0400881 }
882
883 @Test
884 public void testCancelAllNotificationsCancelsChildren() throws Exception {
885 final NotificationRecord parent = generateNotificationRecord(
886 mTestNotificationChannel, 1, "group1", true);
887 final NotificationRecord child = generateNotificationRecord(
888 mTestNotificationChannel, 2, "group1", false);
889
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400890 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds080361e2017-07-13 11:23:12 -0400891 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400892 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds080361e2017-07-13 11:23:12 -0400893 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
894 waitForIdle();
895
896 mBinderService.cancelAllNotifications(PKG, parent.sbn.getUserId());
897 waitForIdle();
Julia Reynolds503ed942017-10-04 16:04:56 -0400898 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500899 }
900
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500901 @Test
Julia Reynolds0839c022017-06-15 15:24:01 -0400902 public void testCancelAllNotificationsMultipleEnqueuedDoesNotCrash() throws Exception {
903 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
904 for (int i = 0; i < 10; i++) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400905 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds0839c022017-06-15 15:24:01 -0400906 sbn.getId(), sbn.getNotification(), sbn.getUserId());
907 }
908 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
909 waitForIdle();
Julia Reynolds080361e2017-07-13 11:23:12 -0400910
Julia Reynolds503ed942017-10-04 16:04:56 -0400911 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds0839c022017-06-15 15:24:01 -0400912 }
913
914 @Test
915 public void testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash() throws Exception {
916 final NotificationRecord parent = generateNotificationRecord(
917 mTestNotificationChannel, 1, "group1", true);
918 final NotificationRecord parentAsChild = generateNotificationRecord(
919 mTestNotificationChannel, 1, "group1", false);
920 final NotificationRecord child = generateNotificationRecord(
921 mTestNotificationChannel, 2, "group1", false);
922
923 // fully post parent notification
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400924 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds0839c022017-06-15 15:24:01 -0400925 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
926 waitForIdle();
927
928 // enqueue the child several times
929 for (int i = 0; i < 10; i++) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400930 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds0839c022017-06-15 15:24:01 -0400931 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
932 }
933 // make the parent a child, which will cancel the child notification
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400934 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds0839c022017-06-15 15:24:01 -0400935 parentAsChild.sbn.getId(), parentAsChild.sbn.getNotification(),
936 parentAsChild.sbn.getUserId());
937 waitForIdle();
Julia Reynolds080361e2017-07-13 11:23:12 -0400938
Julia Reynolds503ed942017-10-04 16:04:56 -0400939 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds0839c022017-06-15 15:24:01 -0400940 }
941
942 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500943 public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
944 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400945 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400946 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400947 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500948 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500949 waitForIdle();
950 StatusBarNotification[] notifs =
951 mBinderService.getActiveNotifications(sbn.getPackageName());
952 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400953 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500954 }
955
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500956 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500957 public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
958 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400959 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400960 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400961 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500962 mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
963 waitForIdle();
964 StatusBarNotification[] notifs =
965 mBinderService.getActiveNotifications(sbn.getPackageName());
966 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400967 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500968 }
969
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500970 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500971 public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
972 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400973 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400974 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500975 mBinderService.cancelAllNotifications(null, sbn.getUserId());
976 waitForIdle();
977 StatusBarNotification[] notifs =
978 mBinderService.getActiveNotifications(sbn.getPackageName());
979 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400980 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500981 }
982
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500983 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500984 public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
985 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400986 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400987 sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500988 // Null pkg is how we signal a user switch.
989 mBinderService.cancelAllNotifications(null, sbn.getUserId());
990 waitForIdle();
991 StatusBarNotification[] notifs =
992 mBinderService.getActiveNotifications(sbn.getPackageName());
993 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400994 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500995 }
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500996
997 @Test
Beverly40239d92017-07-07 10:20:41 -0400998 public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception {
999 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
1000 sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001001 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Beverly40239d92017-07-07 10:20:41 -04001002 sbn.getId(), sbn.getNotification(), sbn.getUserId());
1003 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
1004 waitForIdle();
1005 StatusBarNotification[] notifs =
1006 mBinderService.getActiveNotifications(sbn.getPackageName());
1007 assertEquals(0, notifs.length);
1008 }
1009
1010 @Test
1011 public void testCancelAllNotifications_CancelsNoClearFlag() throws Exception {
1012 final NotificationRecord notif = generateNotificationRecord(
1013 mTestNotificationChannel, 1, "group", true);
1014 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
Julia Reynolds503ed942017-10-04 16:04:56 -04001015 mService.addNotification(notif);
1016 mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true,
Beverly40239d92017-07-07 10:20:41 -04001017 notif.getUserId(), 0, null);
1018 waitForIdle();
1019 StatusBarNotification[] notifs =
1020 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1021 assertEquals(0, notifs.length);
1022 }
1023
1024 @Test
1025 public void testUserInitiatedCancelAllOnClearAll_NoClearFlag() throws Exception {
1026 final NotificationRecord notif = generateNotificationRecord(
1027 mTestNotificationChannel, 1, "group", true);
1028 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
Julia Reynolds503ed942017-10-04 16:04:56 -04001029 mService.addNotification(notif);
Beverly40239d92017-07-07 10:20:41 -04001030
Julia Reynolds503ed942017-10-04 16:04:56 -04001031 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Beverly40239d92017-07-07 10:20:41 -04001032 notif.getUserId());
1033 waitForIdle();
1034 StatusBarNotification[] notifs =
1035 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1036 assertEquals(1, notifs.length);
1037 }
1038
1039 @Test
1040 public void testCancelAllCancelNotificationsFromListener_NoClearFlag() throws Exception {
1041 final NotificationRecord parent = generateNotificationRecord(
1042 mTestNotificationChannel, 1, "group", true);
1043 final NotificationRecord child = generateNotificationRecord(
1044 mTestNotificationChannel, 2, "group", false);
1045 final NotificationRecord child2 = generateNotificationRecord(
1046 mTestNotificationChannel, 3, "group", false);
1047 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
1048 final NotificationRecord newGroup = generateNotificationRecord(
1049 mTestNotificationChannel, 4, "group2", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001050 mService.addNotification(parent);
1051 mService.addNotification(child);
1052 mService.addNotification(child2);
1053 mService.addNotification(newGroup);
1054 mService.getBinderService().cancelNotificationsFromListener(null, null);
Beverly40239d92017-07-07 10:20:41 -04001055 waitForIdle();
1056 StatusBarNotification[] notifs =
1057 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1058 assertEquals(1, notifs.length);
1059 }
1060
1061 @Test
1062 public void testUserInitiatedCancelAllWithGroup_NoClearFlag() throws Exception {
1063 final NotificationRecord parent = generateNotificationRecord(
1064 mTestNotificationChannel, 1, "group", true);
1065 final NotificationRecord child = generateNotificationRecord(
1066 mTestNotificationChannel, 2, "group", false);
1067 final NotificationRecord child2 = generateNotificationRecord(
1068 mTestNotificationChannel, 3, "group", false);
1069 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
1070 final NotificationRecord newGroup = generateNotificationRecord(
1071 mTestNotificationChannel, 4, "group2", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001072 mService.addNotification(parent);
1073 mService.addNotification(child);
1074 mService.addNotification(child2);
1075 mService.addNotification(newGroup);
1076 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Beverly40239d92017-07-07 10:20:41 -04001077 parent.getUserId());
1078 waitForIdle();
1079 StatusBarNotification[] notifs =
1080 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1081 assertEquals(1, notifs.length);
1082 }
1083
1084 @Test
Geoffrey Pitsch415e4542017-04-10 13:12:58 -04001085 public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
1086 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -04001087 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001088 mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -04001089 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch415e4542017-04-10 13:12:58 -04001090 mInternalService.removeForegroundServiceFlagFromNotification(PKG, sbn.getId(),
1091 sbn.getUserId());
1092 waitForIdle();
1093 StatusBarNotification[] notifs =
1094 mBinderService.getActiveNotifications(sbn.getPackageName());
Julia Reynoldse5c60452018-04-30 14:41:36 -04001095 assertEquals(0, notifs[0].getNotification().flags & FLAG_FOREGROUND_SERVICE);
Geoffrey Pitsch415e4542017-04-10 13:12:58 -04001096 }
1097
1098 @Test
Geoffrey Pitsch27684152017-05-02 11:41:31 -04001099 public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception {
1100 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
1101 sbn.getNotification().flags =
Julia Reynoldse5c60452018-04-30 14:41:36 -04001102 Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001103 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Geoffrey Pitsch27684152017-05-02 11:41:31 -04001104 sbn.getId(), sbn.getNotification(), sbn.getUserId());
1105 sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001106 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Geoffrey Pitsch27684152017-05-02 11:41:31 -04001107 sbn.getId(), sbn.getNotification(), sbn.getUserId());
1108 mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
1109 waitForIdle();
1110 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -04001111 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch27684152017-05-02 11:41:31 -04001112 }
1113
1114 @Test
Julia Reynolds40f00d72017-12-12 10:47:32 -05001115 public void testCancelAllCancelNotificationsFromListener_ForegroundServiceFlag()
1116 throws Exception {
1117 final NotificationRecord parent = generateNotificationRecord(
1118 mTestNotificationChannel, 1, "group", true);
1119 final NotificationRecord child = generateNotificationRecord(
1120 mTestNotificationChannel, 2, "group", false);
1121 final NotificationRecord child2 = generateNotificationRecord(
1122 mTestNotificationChannel, 3, "group", false);
Julia Reynoldse5c60452018-04-30 14:41:36 -04001123 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -05001124 final NotificationRecord newGroup = generateNotificationRecord(
1125 mTestNotificationChannel, 4, "group2", false);
1126 mService.addNotification(parent);
1127 mService.addNotification(child);
1128 mService.addNotification(child2);
1129 mService.addNotification(newGroup);
1130 mService.getBinderService().cancelNotificationsFromListener(null, null);
1131 waitForIdle();
1132 StatusBarNotification[] notifs =
1133 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1134 assertEquals(0, notifs.length);
1135 }
1136
1137 @Test
1138 public void testCancelAllCancelNotificationsFromListener_ForegroundServiceFlagWithParameter()
1139 throws Exception {
1140 final NotificationRecord parent = generateNotificationRecord(
1141 mTestNotificationChannel, 1, "group", true);
1142 final NotificationRecord child = generateNotificationRecord(
1143 mTestNotificationChannel, 2, "group", false);
1144 final NotificationRecord child2 = generateNotificationRecord(
1145 mTestNotificationChannel, 3, "group", false);
Julia Reynoldse5c60452018-04-30 14:41:36 -04001146 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -05001147 final NotificationRecord newGroup = generateNotificationRecord(
1148 mTestNotificationChannel, 4, "group2", false);
1149 mService.addNotification(parent);
1150 mService.addNotification(child);
1151 mService.addNotification(child2);
1152 mService.addNotification(newGroup);
1153 String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
1154 child2.sbn.getKey(), newGroup.sbn.getKey()};
1155 mService.getBinderService().cancelNotificationsFromListener(null, keys);
1156 waitForIdle();
1157 StatusBarNotification[] notifs =
1158 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1159 assertEquals(1, notifs.length);
1160 }
1161
1162 @Test
1163 public void testUserInitiatedCancelAllWithGroup_ForegroundServiceFlag() throws Exception {
1164 final NotificationRecord parent = generateNotificationRecord(
1165 mTestNotificationChannel, 1, "group", true);
1166 final NotificationRecord child = generateNotificationRecord(
1167 mTestNotificationChannel, 2, "group", false);
1168 final NotificationRecord child2 = generateNotificationRecord(
1169 mTestNotificationChannel, 3, "group", false);
Julia Reynoldse5c60452018-04-30 14:41:36 -04001170 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -05001171 final NotificationRecord newGroup = generateNotificationRecord(
1172 mTestNotificationChannel, 4, "group2", false);
1173 mService.addNotification(parent);
1174 mService.addNotification(child);
1175 mService.addNotification(child2);
1176 mService.addNotification(newGroup);
1177 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
1178 parent.getUserId());
1179 waitForIdle();
1180 StatusBarNotification[] notifs =
1181 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1182 assertEquals(0, notifs.length);
1183 }
1184
1185 @Test
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001186 public void testFindGroupNotificationsLocked() throws Exception {
1187 // make sure the same notification can be found in both lists and returned
1188 final NotificationRecord group1 = generateNotificationRecord(
1189 mTestNotificationChannel, 1, "group1", true);
Julia Reynolds503ed942017-10-04 16:04:56 -04001190 mService.addEnqueuedNotification(group1);
1191 mService.addNotification(group1);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001192
1193 // should not be returned
1194 final NotificationRecord group2 = generateNotificationRecord(
1195 mTestNotificationChannel, 2, "group2", true);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001196 mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001197 group2.sbn.getId(), group2.sbn.getNotification(), group2.sbn.getUserId());
1198 waitForIdle();
1199
1200 // should not be returned
1201 final NotificationRecord nonGroup = generateNotificationRecord(
1202 mTestNotificationChannel, 3, null, false);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001203 mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001204 nonGroup.sbn.getId(), nonGroup.sbn.getNotification(), nonGroup.sbn.getUserId());
1205 waitForIdle();
1206
1207 // same group, child, should be returned
1208 final NotificationRecord group1Child = generateNotificationRecord(
1209 mTestNotificationChannel, 4, "group1", false);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001210 mBinderService.enqueueNotificationWithTag(PKG, PKG, null, group1Child.sbn.getId(),
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001211 group1Child.sbn.getNotification(), group1Child.sbn.getUserId());
1212 waitForIdle();
1213
1214 List<NotificationRecord> inGroup1 =
Julia Reynolds503ed942017-10-04 16:04:56 -04001215 mService.findGroupNotificationsLocked(PKG, group1.getGroupKey(),
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001216 group1.sbn.getUserId());
1217 assertEquals(3, inGroup1.size());
1218 for (NotificationRecord record : inGroup1) {
1219 assertTrue(record.getGroupKey().equals(group1.getGroupKey()));
1220 assertTrue(record.sbn.getId() == 1 || record.sbn.getId() == 4);
1221 }
1222 }
1223
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001224 @Test
Julia Reynolds40f00d72017-12-12 10:47:32 -05001225 public void testCancelAllNotifications_CancelsNoClearFlagOnGoing() throws Exception {
1226 final NotificationRecord notif = generateNotificationRecord(
1227 mTestNotificationChannel, 1, "group", true);
1228 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
1229 mService.addNotification(notif);
1230 mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0,
1231 Notification.FLAG_ONGOING_EVENT, true, notif.getUserId(), 0, null);
1232 waitForIdle();
1233 StatusBarNotification[] notifs =
1234 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1235 assertEquals(0, notifs.length);
1236 }
1237
1238 @Test
1239 public void testCancelAllCancelNotificationsFromListener_NoClearFlagWithParameter()
1240 throws Exception {
1241 final NotificationRecord parent = generateNotificationRecord(
1242 mTestNotificationChannel, 1, "group", true);
1243 final NotificationRecord child = generateNotificationRecord(
1244 mTestNotificationChannel, 2, "group", false);
1245 final NotificationRecord child2 = generateNotificationRecord(
1246 mTestNotificationChannel, 3, "group", false);
1247 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
1248 final NotificationRecord newGroup = generateNotificationRecord(
1249 mTestNotificationChannel, 4, "group2", false);
1250 mService.addNotification(parent);
1251 mService.addNotification(child);
1252 mService.addNotification(child2);
1253 mService.addNotification(newGroup);
1254 String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
1255 child2.sbn.getKey(), newGroup.sbn.getKey()};
1256 mService.getBinderService().cancelNotificationsFromListener(null, keys);
1257 waitForIdle();
1258 StatusBarNotification[] notifs =
1259 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1260 assertEquals(0, notifs.length);
1261 }
1262
1263 @Test
1264 public void testAppInitiatedCancelAllNotifications_CancelsOnGoingFlag() throws Exception {
1265 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
1266 sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001267 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
Julia Reynolds40f00d72017-12-12 10:47:32 -05001268 sbn.getId(), sbn.getNotification(), sbn.getUserId());
1269 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
1270 waitForIdle();
1271 StatusBarNotification[] notifs =
1272 mBinderService.getActiveNotifications(sbn.getPackageName());
1273 assertEquals(0, notifs.length);
1274 }
1275
1276 @Test
1277 public void testCancelAllNotifications_CancelsOnGoingFlag() throws Exception {
1278 final NotificationRecord notif = generateNotificationRecord(
1279 mTestNotificationChannel, 1, "group", true);
1280 notif.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1281 mService.addNotification(notif);
1282 mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true,
1283 notif.getUserId(), 0, null);
1284 waitForIdle();
1285 StatusBarNotification[] notifs =
1286 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1287 assertEquals(0, notifs.length);
1288 }
1289
1290 @Test
1291 public void testUserInitiatedCancelAllOnClearAll_OnGoingFlag() throws Exception {
1292 final NotificationRecord notif = generateNotificationRecord(
1293 mTestNotificationChannel, 1, "group", true);
1294 notif.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1295 mService.addNotification(notif);
1296
1297 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
1298 notif.getUserId());
1299 waitForIdle();
1300 StatusBarNotification[] notifs =
1301 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1302 assertEquals(1, notifs.length);
1303 }
1304
1305 @Test
1306 public void testCancelAllCancelNotificationsFromListener_OnGoingFlag() throws Exception {
1307 final NotificationRecord parent = generateNotificationRecord(
1308 mTestNotificationChannel, 1, "group", true);
1309 final NotificationRecord child = generateNotificationRecord(
1310 mTestNotificationChannel, 2, "group", false);
1311 final NotificationRecord child2 = generateNotificationRecord(
1312 mTestNotificationChannel, 3, "group", false);
1313 child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1314 final NotificationRecord newGroup = generateNotificationRecord(
1315 mTestNotificationChannel, 4, "group2", false);
1316 mService.addNotification(parent);
1317 mService.addNotification(child);
1318 mService.addNotification(child2);
1319 mService.addNotification(newGroup);
1320 mService.getBinderService().cancelNotificationsFromListener(null, null);
1321 waitForIdle();
1322 StatusBarNotification[] notifs =
1323 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1324 assertEquals(1, notifs.length);
1325 }
1326
1327 @Test
1328 public void testCancelAllCancelNotificationsFromListener_OnGoingFlagWithParameter()
1329 throws Exception {
1330 final NotificationRecord parent = generateNotificationRecord(
1331 mTestNotificationChannel, 1, "group", true);
1332 final NotificationRecord child = generateNotificationRecord(
1333 mTestNotificationChannel, 2, "group", false);
1334 final NotificationRecord child2 = generateNotificationRecord(
1335 mTestNotificationChannel, 3, "group", false);
1336 child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1337 final NotificationRecord newGroup = generateNotificationRecord(
1338 mTestNotificationChannel, 4, "group2", false);
1339 mService.addNotification(parent);
1340 mService.addNotification(child);
1341 mService.addNotification(child2);
1342 mService.addNotification(newGroup);
1343 String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
1344 child2.sbn.getKey(), newGroup.sbn.getKey()};
1345 mService.getBinderService().cancelNotificationsFromListener(null, keys);
1346 waitForIdle();
1347 StatusBarNotification[] notifs =
1348 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1349 assertEquals(0, notifs.length);
1350 }
1351
1352 @Test
1353 public void testUserInitiatedCancelAllWithGroup_OnGoingFlag() throws Exception {
1354 final NotificationRecord parent = generateNotificationRecord(
1355 mTestNotificationChannel, 1, "group", true);
1356 final NotificationRecord child = generateNotificationRecord(
1357 mTestNotificationChannel, 2, "group", false);
1358 final NotificationRecord child2 = generateNotificationRecord(
1359 mTestNotificationChannel, 3, "group", false);
1360 child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1361 final NotificationRecord newGroup = generateNotificationRecord(
1362 mTestNotificationChannel, 4, "group2", false);
1363 mService.addNotification(parent);
1364 mService.addNotification(child);
1365 mService.addNotification(child2);
1366 mService.addNotification(newGroup);
1367 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
1368 parent.getUserId());
1369 waitForIdle();
1370 StatusBarNotification[] notifs =
1371 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1372 assertEquals(1, notifs.length);
1373 }
1374
1375 @Test
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001376 public void testTvExtenderChannelOverride_onTv() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001377 mService.setIsTelevision(true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001378 mService.setPreferencesHelper(mPreferencesHelper);
1379 when(mPreferencesHelper.getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001380 anyString(), anyInt(), eq("foo"), anyBoolean())).thenReturn(
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001381 new NotificationChannel("foo", "foo", IMPORTANCE_HIGH));
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001382
Julia Reynoldsbad42972017-04-25 13:52:49 -04001383 Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001384 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -04001385 generateNotificationRecord(null, tv).getNotification(), 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001386 verify(mPreferencesHelper, times(1)).getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001387 anyString(), anyInt(), eq("foo"), anyBoolean());
1388 }
1389
1390 @Test
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001391 public void testTvExtenderChannelOverride_notOnTv() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001392 mService.setIsTelevision(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001393 mService.setPreferencesHelper(mPreferencesHelper);
1394 when(mPreferencesHelper.getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001395 anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001396 mTestNotificationChannel);
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001397
Julia Reynoldsbad42972017-04-25 13:52:49 -04001398 Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001399 mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -04001400 generateNotificationRecord(null, tv).getNotification(), 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001401 verify(mPreferencesHelper, times(1)).getNotificationChannel(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001402 anyString(), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean());
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001403 }
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001404
1405 @Test
Julia Reynoldsfc9767b2018-01-22 17:45:16 -05001406 public void testUpdateAppNotifyCreatorBlock() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001407 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldsfc9767b2018-01-22 17:45:16 -05001408
1409 mBinderService.setNotificationsEnabledForPackage(PKG, 0, false);
1410 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1411 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1412
1413 assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
1414 captor.getValue().getAction());
1415 assertEquals(PKG, captor.getValue().getPackage());
1416 assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1417 }
1418
1419 @Test
1420 public void testUpdateAppNotifyCreatorUnblock() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001421 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldsfc9767b2018-01-22 17:45:16 -05001422
1423 mBinderService.setNotificationsEnabledForPackage(PKG, 0, true);
1424 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1425 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1426
1427 assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
1428 captor.getValue().getAction());
1429 assertEquals(PKG, captor.getValue().getPackage());
1430 assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
1431 }
1432
1433 @Test
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001434 public void testUpdateChannelNotifyCreatorBlock() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001435 mService.setPreferencesHelper(mPreferencesHelper);
1436 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001437 eq(mTestNotificationChannel.getId()), anyBoolean()))
1438 .thenReturn(mTestNotificationChannel);
1439
1440 NotificationChannel updatedChannel =
1441 new NotificationChannel(mTestNotificationChannel.getId(),
1442 mTestNotificationChannel.getName(), IMPORTANCE_NONE);
1443
1444 mBinderService.updateNotificationChannelForPackage(PKG, 0, updatedChannel);
1445 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1446 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1447
1448 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED,
1449 captor.getValue().getAction());
1450 assertEquals(PKG, captor.getValue().getPackage());
1451 assertEquals(mTestNotificationChannel.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001452 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001453 assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1454 }
1455
1456 @Test
1457 public void testUpdateChannelNotifyCreatorUnblock() throws Exception {
1458 NotificationChannel existingChannel =
1459 new NotificationChannel(mTestNotificationChannel.getId(),
1460 mTestNotificationChannel.getName(), IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001461 mService.setPreferencesHelper(mPreferencesHelper);
1462 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001463 eq(mTestNotificationChannel.getId()), anyBoolean()))
1464 .thenReturn(existingChannel);
1465
1466 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
1467 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1468 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1469
1470 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED,
1471 captor.getValue().getAction());
1472 assertEquals(PKG, captor.getValue().getPackage());
1473 assertEquals(mTestNotificationChannel.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001474 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001475 assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1476 }
1477
1478 @Test
1479 public void testUpdateChannelNoNotifyCreatorOtherChanges() throws Exception {
1480 NotificationChannel existingChannel =
1481 new NotificationChannel(mTestNotificationChannel.getId(),
1482 mTestNotificationChannel.getName(), IMPORTANCE_MAX);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001483 mService.setPreferencesHelper(mPreferencesHelper);
1484 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001485 eq(mTestNotificationChannel.getId()), anyBoolean()))
1486 .thenReturn(existingChannel);
1487
1488 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
1489 verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
1490 }
1491
1492 @Test
1493 public void testUpdateGroupNotifyCreatorBlock() throws Exception {
1494 NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001495 mService.setPreferencesHelper(mPreferencesHelper);
1496 when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001497 .thenReturn(existing);
1498
1499 NotificationChannelGroup updated = new NotificationChannelGroup("id", "name");
1500 updated.setBlocked(true);
1501
1502 mBinderService.updateNotificationChannelGroupForPackage(PKG, 0, updated);
1503 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1504 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1505
1506 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED,
1507 captor.getValue().getAction());
1508 assertEquals(PKG, captor.getValue().getPackage());
1509 assertEquals(existing.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001510 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001511 assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1512 }
1513
1514 @Test
1515 public void testUpdateGroupNotifyCreatorUnblock() throws Exception {
1516 NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
1517 existing.setBlocked(true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001518 mService.setPreferencesHelper(mPreferencesHelper);
1519 when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001520 .thenReturn(existing);
1521
1522 mBinderService.updateNotificationChannelGroupForPackage(
1523 PKG, 0, new NotificationChannelGroup("id", "name"));
1524 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1525 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1526
1527 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED,
1528 captor.getValue().getAction());
1529 assertEquals(PKG, captor.getValue().getPackage());
1530 assertEquals(existing.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001531 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001532 assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1533 }
1534
1535 @Test
1536 public void testUpdateGroupNoNotifyCreatorOtherChanges() throws Exception {
1537 NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001538 mService.setPreferencesHelper(mPreferencesHelper);
1539 when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001540 .thenReturn(existing);
1541
1542 mBinderService.updateNotificationChannelGroupForPackage(
1543 PKG, 0, new NotificationChannelGroup("id", "new name"));
1544 verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
1545 }
1546
1547 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001548 public void testCreateChannelNotifyListener() throws Exception {
1549 List<String> associations = new ArrayList<>();
1550 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001551 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001552 mService.setPreferencesHelper(mPreferencesHelper);
1553 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001554 eq(mTestNotificationChannel.getId()), anyBoolean()))
1555 .thenReturn(mTestNotificationChannel);
1556 NotificationChannel channel2 = new NotificationChannel("a", "b", IMPORTANCE_LOW);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001557 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001558 eq(channel2.getId()), anyBoolean()))
1559 .thenReturn(channel2);
1560
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001561 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001562 mBinderService.createNotificationChannels(PKG,
1563 new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001564 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001565 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001566 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001567 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001568 eq(Process.myUserHandle()), eq(channel2),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001569 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
1570 }
1571
1572 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001573 public void testCreateChannelGroupNotifyListener() throws Exception {
1574 List<String> associations = new ArrayList<>();
1575 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001576 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001577 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001578 NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
1579 NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
1580
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001581 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001582 mBinderService.createNotificationChannelGroups(PKG,
1583 new ParceledListSlice(Arrays.asList(group1, group2)));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001584 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001585 eq(Process.myUserHandle()), eq(group1),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001586 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001587 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001588 eq(Process.myUserHandle()), eq(group2),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001589 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
1590 }
1591
1592 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001593 public void testUpdateChannelNotifyListener() throws Exception {
1594 List<String> associations = new ArrayList<>();
1595 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001596 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001597 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001598 mTestNotificationChannel.setLightColor(Color.CYAN);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001599 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001600 eq(mTestNotificationChannel.getId()), anyBoolean()))
1601 .thenReturn(mTestNotificationChannel);
1602
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001603 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001604 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001605 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001606 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001607 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1608 }
1609
1610 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001611 public void testDeleteChannelNotifyListener() throws Exception {
1612 List<String> associations = new ArrayList<>();
1613 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001614 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001615 mService.setPreferencesHelper(mPreferencesHelper);
1616 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001617 eq(mTestNotificationChannel.getId()), anyBoolean()))
1618 .thenReturn(mTestNotificationChannel);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001619 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001620 mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001621 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001622 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001623 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
1624 }
1625
1626 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001627 public void testDeleteChannelGroupNotifyListener() throws Exception {
1628 List<String> associations = new ArrayList<>();
1629 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001630 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001631 NotificationChannelGroup ncg = new NotificationChannelGroup("a", "b/c");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001632 mService.setPreferencesHelper(mPreferencesHelper);
1633 when(mPreferencesHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt()))
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001634 .thenReturn(ncg);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001635 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001636 mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001637 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001638 eq(Process.myUserHandle()), eq(ncg),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001639 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
1640 }
1641
1642 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001643 public void testUpdateNotificationChannelFromPrivilegedListener_success() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001644 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001645 List<String> associations = new ArrayList<>();
1646 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001647 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001648 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001649 eq(mTestNotificationChannel.getId()), anyBoolean()))
1650 .thenReturn(mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001651
1652 mBinderService.updateNotificationChannelFromPrivilegedListener(
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001653 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001654
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001655 verify(mPreferencesHelper, times(1)).updateNotificationChannel(
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001656 anyString(), anyInt(), any(), anyBoolean());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001657
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001658 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001659 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001660 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1661 }
1662
1663 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001664 public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001665 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001666 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001667 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001668
1669 try {
1670 mBinderService.updateNotificationChannelFromPrivilegedListener(
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001671 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001672 fail("listeners that don't have a companion device shouldn't be able to call this");
1673 } catch (SecurityException e) {
1674 // pass
1675 }
1676
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001677 verify(mPreferencesHelper, never()).updateNotificationChannel(
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001678 anyString(), anyInt(), any(), anyBoolean());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001679
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001680 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001681 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
1682 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1683 }
1684
1685 @Test
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001686 public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001687 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001688 List<String> associations = new ArrayList<>();
1689 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001690 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001691 mListener = mock(ManagedServices.ManagedServiceInfo.class);
Julia Reynolds4da79702017-06-01 11:06:10 -04001692 mListener.component = new ComponentName(PKG, PKG);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001693 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001694 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001695
1696 try {
1697 mBinderService.updateNotificationChannelFromPrivilegedListener(
1698 null, PKG, UserHandle.ALL, mTestNotificationChannel);
1699 fail("incorrectly allowed a change to a user listener cannot see");
1700 } catch (SecurityException e) {
1701 // pass
1702 }
1703
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001704 verify(mPreferencesHelper, never()).updateNotificationChannel(
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001705 anyString(), anyInt(), any(), anyBoolean());
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001706
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001707 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001708 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001709 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1710 }
1711
1712 @Test
Julia Reynolds48a6ed92018-10-22 12:52:03 -04001713 public void testGetNotificationChannelFromPrivilegedListener_cdm_success() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001714 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001715 List<String> associations = new ArrayList<>();
1716 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001717 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001718
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001719 mBinderService.getNotificationChannelsFromPrivilegedListener(
1720 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001721
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001722 verify(mPreferencesHelper, times(1)).getNotificationChannels(
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001723 anyString(), anyInt(), anyBoolean());
1724 }
1725
1726 @Test
Julia Reynolds48a6ed92018-10-22 12:52:03 -04001727 public void testGetNotificationChannelFromPrivilegedListener_cdm_noAccess() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001728 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001729 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001730 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001731
1732 try {
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001733 mBinderService.getNotificationChannelsFromPrivilegedListener(
1734 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001735 fail("listeners that don't have a companion device shouldn't be able to call this");
1736 } catch (SecurityException e) {
1737 // pass
1738 }
1739
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001740 verify(mPreferencesHelper, never()).getNotificationChannels(
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001741 anyString(), anyInt(), anyBoolean());
1742 }
1743
1744 @Test
Julia Reynolds48a6ed92018-10-22 12:52:03 -04001745 public void testGetNotificationChannelFromPrivilegedListener_assistant_success()
1746 throws Exception {
1747 mService.setPreferencesHelper(mPreferencesHelper);
1748 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(new ArrayList<>());
1749 when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
1750
1751 mBinderService.getNotificationChannelsFromPrivilegedListener(
1752 null, PKG, Process.myUserHandle());
1753
1754 verify(mPreferencesHelper, times(1)).getNotificationChannels(
1755 anyString(), anyInt(), anyBoolean());
1756 }
1757
1758 @Test
Julia Reynolds268647a2018-10-25 16:54:27 -04001759 public void testGetNotificationChannelFromPrivilegedListener_assistant_noAccess()
1760 throws Exception {
Julia Reynolds48a6ed92018-10-22 12:52:03 -04001761 mService.setPreferencesHelper(mPreferencesHelper);
1762 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(new ArrayList<>());
1763 when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(false);
1764
1765 try {
1766 mBinderService.getNotificationChannelsFromPrivilegedListener(
1767 null, PKG, Process.myUserHandle());
1768 fail("listeners that don't have a companion device shouldn't be able to call this");
1769 } catch (SecurityException e) {
1770 // pass
1771 }
1772
1773 verify(mPreferencesHelper, never()).getNotificationChannels(
1774 anyString(), anyInt(), anyBoolean());
1775 }
1776
1777 @Test
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001778 public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001779 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001780 List<String> associations = new ArrayList<>();
1781 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001782 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001783 mListener = mock(ManagedServices.ManagedServiceInfo.class);
1784 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001785 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001786
1787 try {
1788 mBinderService.getNotificationChannelsFromPrivilegedListener(
1789 null, PKG, Process.myUserHandle());
1790 fail("listener getting channels from a user they cannot see");
1791 } catch (SecurityException e) {
1792 // pass
1793 }
1794
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001795 verify(mPreferencesHelper, never()).getNotificationChannels(
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001796 anyString(), anyInt(), anyBoolean());
1797 }
1798
1799 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001800 public void testGetNotificationChannelGroupsFromPrivilegedListener_success() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001801 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001802 List<String> associations = new ArrayList<>();
1803 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001804 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001805
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001806 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1807 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001808
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001809 verify(mPreferencesHelper, times(1)).getNotificationChannelGroups(anyString(), anyInt());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001810 }
1811
1812 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001813 public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001814 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001815 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001816 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001817
1818 try {
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001819 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1820 null, PKG, Process.myUserHandle());
1821 fail("listeners that don't have a companion device shouldn't be able to call this");
1822 } catch (SecurityException e) {
1823 // pass
1824 }
1825
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001826 verify(mPreferencesHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001827 }
1828
1829 @Test
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001830 public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001831 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001832 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001833 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001834 mListener = mock(ManagedServices.ManagedServiceInfo.class);
1835 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001836 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynolds27c0a962018-12-10 12:37:28 -05001837 try {
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001838 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1839 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001840 fail("listeners that don't have a companion device shouldn't be able to call this");
1841 } catch (SecurityException e) {
1842 // pass
1843 }
1844
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001845 verify(mPreferencesHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001846 }
Julia Reynoldsda781472017-04-12 09:41:16 -04001847
1848 @Test
Julia Reynoldsda781472017-04-12 09:41:16 -04001849 public void testHasCompanionDevice_failure() throws Exception {
1850 when(mCompanionMgr.getAssociations(anyString(), anyInt())).thenThrow(
1851 new IllegalArgumentException());
Julia Reynolds503ed942017-10-04 16:04:56 -04001852 mService.hasCompanionDevice(mListener);
Julia Reynoldsda781472017-04-12 09:41:16 -04001853 }
Julia Reynolds727a7282017-04-13 10:54:01 -04001854
1855 @Test
Julia Reynolds727a7282017-04-13 10:54:01 -04001856 public void testHasCompanionDevice_noService() throws Exception {
Annie Meng8b646fd2019-02-01 18:46:42 +00001857 mService = new TestableNotificationManagerService(mContext, mUserMangerService);
Julia Reynolds727a7282017-04-13 10:54:01 -04001858
Julia Reynolds503ed942017-10-04 16:04:56 -04001859 assertFalse(mService.hasCompanionDevice(mListener));
Julia Reynolds727a7282017-04-13 10:54:01 -04001860 }
1861
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001862 @Test
1863 public void testSnoozeRunnable_snoozeNonGrouped() throws Exception {
1864 final NotificationRecord nonGrouped = generateNotificationRecord(
1865 mTestNotificationChannel, 1, null, false);
1866 final NotificationRecord grouped = generateNotificationRecord(
1867 mTestNotificationChannel, 2, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001868 mService.addNotification(grouped);
1869 mService.addNotification(nonGrouped);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001870
1871 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001872 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001873 nonGrouped.getKey(), 100, null);
1874 snoozeNotificationRunnable.run();
1875
1876 // only snooze the one notification
1877 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
Julia Reynolds503ed942017-10-04 16:04:56 -04001878 assertTrue(nonGrouped.getStats().hasSnoozed());
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001879 }
1880
1881 @Test
1882 public void testSnoozeRunnable_snoozeSummary_withChildren() throws Exception {
1883 final NotificationRecord parent = generateNotificationRecord(
1884 mTestNotificationChannel, 1, "group", true);
1885 final NotificationRecord child = generateNotificationRecord(
1886 mTestNotificationChannel, 2, "group", false);
1887 final NotificationRecord child2 = generateNotificationRecord(
1888 mTestNotificationChannel, 3, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001889 mService.addNotification(parent);
1890 mService.addNotification(child);
1891 mService.addNotification(child2);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001892
1893 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001894 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001895 parent.getKey(), 100, null);
1896 snoozeNotificationRunnable.run();
1897
1898 // snooze parent and children
1899 verify(mSnoozeHelper, times(3)).snooze(any(NotificationRecord.class), anyLong());
1900 }
1901
1902 @Test
1903 public void testSnoozeRunnable_snoozeGroupChild_fellowChildren() throws Exception {
1904 final NotificationRecord parent = generateNotificationRecord(
1905 mTestNotificationChannel, 1, "group", true);
1906 final NotificationRecord child = generateNotificationRecord(
1907 mTestNotificationChannel, 2, "group", false);
1908 final NotificationRecord child2 = generateNotificationRecord(
1909 mTestNotificationChannel, 3, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001910 mService.addNotification(parent);
1911 mService.addNotification(child);
1912 mService.addNotification(child2);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001913
1914 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001915 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001916 child2.getKey(), 100, null);
1917 snoozeNotificationRunnable.run();
1918
1919 // only snooze the one child
1920 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
1921 }
1922
1923 @Test
1924 public void testSnoozeRunnable_snoozeGroupChild_onlyChildOfSummary() throws Exception {
1925 final NotificationRecord parent = generateNotificationRecord(
1926 mTestNotificationChannel, 1, "group", true);
1927 assertTrue(parent.sbn.getNotification().isGroupSummary());
1928 final NotificationRecord child = generateNotificationRecord(
1929 mTestNotificationChannel, 2, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001930 mService.addNotification(parent);
1931 mService.addNotification(child);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001932
1933 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001934 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001935 child.getKey(), 100, null);
1936 snoozeNotificationRunnable.run();
1937
1938 // snooze child and summary
1939 verify(mSnoozeHelper, times(2)).snooze(any(NotificationRecord.class), anyLong());
1940 }
1941
1942 @Test
1943 public void testSnoozeRunnable_snoozeGroupChild_noOthersInGroup() throws Exception {
1944 final NotificationRecord child = generateNotificationRecord(
1945 mTestNotificationChannel, 2, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001946 mService.addNotification(child);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001947
1948 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001949 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001950 child.getKey(), 100, null);
1951 snoozeNotificationRunnable.run();
1952
1953 // snooze child only
1954 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
1955 }
1956
1957 @Test
1958 public void testPostGroupChild_unsnoozeParent() throws Exception {
1959 final NotificationRecord child = generateNotificationRecord(
1960 mTestNotificationChannel, 2, "group", false);
1961
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001962 mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001963 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
1964 waitForIdle();
1965
1966 verify(mSnoozeHelper, times(1)).repostGroupSummary(
1967 anyString(), anyInt(), eq(child.getGroupKey()));
1968 }
1969
1970 @Test
1971 public void testPostNonGroup_noUnsnoozing() throws Exception {
1972 final NotificationRecord record = generateNotificationRecord(
1973 mTestNotificationChannel, 2, null, false);
1974
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001975 mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001976 record.sbn.getId(), record.sbn.getNotification(), record.sbn.getUserId());
1977 waitForIdle();
1978
1979 verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
1980 }
1981
1982 @Test
1983 public void testPostGroupSummary_noUnsnoozing() throws Exception {
1984 final NotificationRecord parent = generateNotificationRecord(
1985 mTestNotificationChannel, 2, "group", true);
1986
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04001987 mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001988 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
1989 waitForIdle();
1990
1991 verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
1992 }
Julia Reynoldsb852e562017-06-06 16:14:18 -04001993
1994 @Test
Julia Reynolds92febc32017-10-26 11:30:31 -04001995 public void testSetListenerAccessForUser() throws Exception {
1996 UserHandle user = UserHandle.of(10);
1997 ComponentName c = ComponentName.unflattenFromString("package/Component");
1998 try {
1999 mBinderService.setNotificationListenerAccessGrantedForUser(
2000 c, user.getIdentifier(), true);
2001 } catch (SecurityException e) {
2002 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2003 throw e;
2004 }
2005 }
2006
2007 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
2008 verify(mListeners, times(1)).setPackageOrComponentEnabled(
2009 c.flattenToString(), user.getIdentifier(), true, true);
2010 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2011 c.flattenToString(), user.getIdentifier(), false, true);
2012 verify(mAssistants, never()).setPackageOrComponentEnabled(
2013 any(), anyInt(), anyBoolean(), anyBoolean());
2014 }
2015
2016 @Test
2017 public void testSetAssistantAccessForUser() throws Exception {
2018 UserHandle user = UserHandle.of(10);
2019 ComponentName c = ComponentName.unflattenFromString("package/Component");
2020 try {
2021 mBinderService.setNotificationAssistantAccessGrantedForUser(
2022 c, user.getIdentifier(), 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(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
2030 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
2031 c.flattenToString(), user.getIdentifier(), true, true);
2032 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2033 c.flattenToString(), user.getIdentifier(), false, true);
2034 verify(mListeners, never()).setPackageOrComponentEnabled(
2035 any(), anyInt(), anyBoolean(), anyBoolean());
2036 }
2037
2038 @Test
Fabian Kozynskid9425662019-01-29 13:08:30 -05002039 public void testGetAssistantAllowedForUser() throws Exception {
2040 UserHandle user = UserHandle.of(10);
2041 try {
2042 mBinderService.getAllowedNotificationAssistantForUser(user.getIdentifier());
2043 } catch (IllegalStateException e) {
2044 if (!e.getMessage().contains("At most one NotificationAssistant")) {
2045 throw e;
2046 }
2047 }
2048 verify(mAssistants, times(1)).getAllowedComponents(user.getIdentifier());
2049 }
2050
2051 @Test
2052 public void testGetAssistantAllowed() throws Exception {
2053 try {
2054 mBinderService.getAllowedNotificationAssistant();
2055 } catch (IllegalStateException e) {
2056 if (!e.getMessage().contains("At most one NotificationAssistant")) {
2057 throw e;
2058 }
2059 }
2060 verify(mAssistants, times(1)).getAllowedComponents(0);
2061 }
2062
2063 @Test
Julia Reynolds92febc32017-10-26 11:30:31 -04002064 public void testSetDndAccessForUser() throws Exception {
2065 UserHandle user = UserHandle.of(10);
2066 ComponentName c = ComponentName.unflattenFromString("package/Component");
2067 try {
2068 mBinderService.setNotificationPolicyAccessGrantedForUser(
2069 c.getPackageName(), user.getIdentifier(), true);
2070 } catch (SecurityException e) {
2071 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2072 throw e;
2073 }
2074 }
2075
2076 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
2077 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2078 c.getPackageName(), user.getIdentifier(), true, true);
2079 verify(mAssistants, never()).setPackageOrComponentEnabled(
2080 any(), anyInt(), anyBoolean(), anyBoolean());
2081 verify(mListeners, never()).setPackageOrComponentEnabled(
2082 any(), anyInt(), anyBoolean(), anyBoolean());
2083 }
2084
2085 @Test
Julia Reynoldsb852e562017-06-06 16:14:18 -04002086 public void testSetListenerAccess() throws Exception {
2087 ComponentName c = ComponentName.unflattenFromString("package/Component");
2088 try {
2089 mBinderService.setNotificationListenerAccessGranted(c, true);
2090 } catch (SecurityException e) {
2091 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2092 throw e;
2093 }
2094 }
2095
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002096 verify(mListeners, times(1)).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04002097 c.flattenToString(), 0, true, true);
2098 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2099 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002100 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04002101 any(), anyInt(), anyBoolean(), anyBoolean());
2102 }
2103
2104 @Test
2105 public void testSetAssistantAccess() throws Exception {
2106 ComponentName c = ComponentName.unflattenFromString("package/Component");
2107 try {
2108 mBinderService.setNotificationAssistantAccessGranted(c, true);
2109 } catch (SecurityException e) {
2110 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2111 throw e;
2112 }
2113 }
2114
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002115 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04002116 c.flattenToString(), 0, true, true);
2117 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2118 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002119 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04002120 any(), anyInt(), anyBoolean(), anyBoolean());
2121 }
2122
2123 @Test
Fabian Kozynskid9425662019-01-29 13:08:30 -05002124 public void testSetAssistantAccess_nullWithAllowedAssistant() throws Exception {
2125 ArrayList<ComponentName> componentList = new ArrayList<>();
2126 ComponentName c = ComponentName.unflattenFromString("package/Component");
2127 componentList.add(c);
2128 when(mAssistants.getAllowedComponents(anyInt())).thenReturn(componentList);
2129
2130 try {
2131 mBinderService.setNotificationAssistantAccessGranted(null, true);
2132 } catch (SecurityException e) {
2133 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2134 throw e;
2135 }
2136 }
2137
2138 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
2139 c.flattenToString(), 0, true, false);
2140 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2141 c.flattenToString(), 0, false, false);
2142 verify(mListeners, never()).setPackageOrComponentEnabled(
2143 any(), anyInt(), anyBoolean(), anyBoolean());
2144 }
2145
2146 @Test
2147 public void testSetAssistantAccessForUser_nullWithAllowedAssistant() throws Exception {
2148 UserHandle user = UserHandle.of(10);
2149 ArrayList<ComponentName> componentList = new ArrayList<>();
2150 ComponentName c = ComponentName.unflattenFromString("package/Component");
2151 componentList.add(c);
2152 when(mAssistants.getAllowedComponents(anyInt())).thenReturn(componentList);
2153
2154 try {
2155 mBinderService.setNotificationAssistantAccessGrantedForUser(
2156 null, user.getIdentifier(), true);
2157 } catch (SecurityException e) {
2158 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2159 throw e;
2160 }
2161 }
2162
2163 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
2164 c.flattenToString(), user.getIdentifier(), true, false);
2165 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2166 c.flattenToString(), user.getIdentifier(), false, false);
2167 verify(mListeners, never()).setPackageOrComponentEnabled(
2168 any(), anyInt(), anyBoolean(), anyBoolean());
2169 }
2170
2171 @Test
Julia Reynoldsb852e562017-06-06 16:14:18 -04002172 public void testSetDndAccess() throws Exception {
2173 ComponentName c = ComponentName.unflattenFromString("package/Component");
2174 try {
2175 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
2176 } catch (SecurityException e) {
2177 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2178 throw e;
2179 }
2180 }
2181
2182 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2183 c.getPackageName(), 0, true, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002184 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04002185 any(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002186 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04002187 any(), anyInt(), anyBoolean(), anyBoolean());
2188 }
Julia Reynolds68263d12017-06-21 14:21:19 -04002189
2190 @Test
2191 public void testSetListenerAccess_doesNothingOnLowRam() throws Exception {
2192 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2193 ComponentName c = ComponentName.unflattenFromString("package/Component");
2194 mBinderService.setNotificationListenerAccessGranted(c, true);
2195
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002196 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002197 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04002198 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002199 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002200 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04002201 any(), anyInt(), anyBoolean(), anyBoolean());
2202 }
2203
2204 @Test
2205 public void testSetAssistantAccess_doesNothingOnLowRam() throws Exception {
2206 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2207 ComponentName c = ComponentName.unflattenFromString("package/Component");
2208 mBinderService.setNotificationAssistantAccessGranted(c, true);
2209
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002210 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002211 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04002212 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002213 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002214 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04002215 any(), anyInt(), anyBoolean(), anyBoolean());
2216 }
2217
2218 @Test
2219 public void testSetDndAccess_doesNothingOnLowRam() throws Exception {
2220 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2221 ComponentName c = ComponentName.unflattenFromString("package/Component");
2222 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
2223
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002224 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002225 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04002226 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002227 anyString(), anyInt(), anyBoolean(), anyBoolean());
2228 verify(mAssistants, never()).setPackageOrComponentEnabled(
2229 any(), anyInt(), anyBoolean(), anyBoolean());
2230 }
2231
2232 @Test
2233 public void testSetListenerAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
2234 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
2235 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2236 ComponentName c = ComponentName.unflattenFromString("package/Component");
2237 try {
2238 mBinderService.setNotificationListenerAccessGranted(c, true);
2239 } catch (SecurityException e) {
2240 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2241 throw e;
2242 }
2243 }
2244
2245 verify(mListeners, times(1)).setPackageOrComponentEnabled(
2246 c.flattenToString(), 0, true, true);
2247 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04002248 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002249 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04002250 any(), anyInt(), anyBoolean(), anyBoolean());
2251 }
Julia Reynolds8aebf352017-06-26 11:35:33 -04002252
2253 @Test
Julia Reynoldse1816412017-10-24 10:39:11 -04002254 public void testSetAssistantAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
2255 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
2256 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2257 ComponentName c = ComponentName.unflattenFromString("package/Component");
2258 try {
2259 mBinderService.setNotificationAssistantAccessGranted(c, true);
2260 } catch (SecurityException e) {
2261 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2262 throw e;
2263 }
2264 }
2265
2266 verify(mListeners, never()).setPackageOrComponentEnabled(
2267 anyString(), anyInt(), anyBoolean(), anyBoolean());
2268 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2269 c.flattenToString(), 0, false, true);
2270 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
2271 c.flattenToString(), 0, true, true);
2272 }
2273
2274 @Test
2275 public void testSetDndAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
2276 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
2277 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2278 ComponentName c = ComponentName.unflattenFromString("package/Component");
2279 try {
2280 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
2281 } catch (SecurityException e) {
2282 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2283 throw e;
2284 }
2285 }
2286
2287 verify(mListeners, never()).setPackageOrComponentEnabled(
2288 anyString(), anyInt(), anyBoolean(), anyBoolean());
2289 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2290 c.getPackageName(), 0, true, true);
2291 verify(mAssistants, never()).setPackageOrComponentEnabled(
2292 any(), anyInt(), anyBoolean(), anyBoolean());
2293 }
2294
2295 @Test
Julia Reynolds8aebf352017-06-26 11:35:33 -04002296 public void testOnlyAutogroupIfGroupChanged_noPriorNoti_autogroups() throws Exception {
2297 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002298 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002299 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002300 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002301 runnable.run();
2302 waitForIdle();
2303
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002304 verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002305 }
2306
2307 @Test
2308 public void testOnlyAutogroupIfGroupChanged_groupChanged_autogroups()
2309 throws Exception {
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002310 NotificationRecord r =
2311 generateNotificationRecord(mTestNotificationChannel, 0, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002312 mService.addNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002313
2314 r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002315 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002316 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002317 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002318 runnable.run();
2319 waitForIdle();
2320
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002321 verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002322 }
2323
2324 @Test
2325 public void testOnlyAutogroupIfGroupChanged_noGroupChanged_autogroups()
2326 throws Exception {
Julia Reynolds4db59552017-06-30 13:34:01 -04002327 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group",
2328 false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002329 mService.addNotification(r);
2330 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002331
2332 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002333 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002334 runnable.run();
2335 waitForIdle();
2336
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002337 verify(mGroupHelper, never()).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002338 }
Beverly40239d92017-07-07 10:20:41 -04002339
Julia Reynolds4db59552017-06-30 13:34:01 -04002340 @Test
Brad Stenningd2e7a972018-10-01 09:08:42 -07002341 public void testDontAutogroupIfCritical() throws Exception {
2342 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
2343 r.setCriticality(CriticalNotificationExtractor.CRITICAL_LOW);
2344 mService.addEnqueuedNotification(r);
2345 NotificationManagerService.PostNotificationRunnable runnable =
2346 mService.new PostNotificationRunnable(r.getKey());
2347 runnable.run();
2348
2349 r = generateNotificationRecord(mTestNotificationChannel, 1, null, false);
2350 r.setCriticality(CriticalNotificationExtractor.CRITICAL);
2351 runnable = mService.new PostNotificationRunnable(r.getKey());
2352 mService.addEnqueuedNotification(r);
2353
2354 runnable.run();
2355 waitForIdle();
2356
2357 verify(mGroupHelper, never()).onNotificationPosted(any(), anyBoolean());
2358 }
2359
2360 @Test
Julia Reynolds4db59552017-06-30 13:34:01 -04002361 public void testNoFakeColorizedPermission() throws Exception {
2362 when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED);
2363 Notification.Builder nb = new Notification.Builder(mContext,
2364 mTestNotificationChannel.getId())
2365 .setContentTitle("foo")
2366 .setColorized(true)
2367 .setFlag(Notification.FLAG_CAN_COLORIZE, true)
2368 .setSmallIcon(android.R.drawable.sym_def_app_icon);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002369 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
2370 nb.build(), new UserHandle(mUid), null, 0);
Julia Reynolds4db59552017-06-30 13:34:01 -04002371 NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
2372
2373 mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
2374 nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
2375 waitForIdle();
2376
Julia Reynolds503ed942017-10-04 16:04:56 -04002377 NotificationRecord posted = mService.findNotificationLocked(
Julia Reynolds4db59552017-06-30 13:34:01 -04002378 PKG, null, nr.sbn.getId(), nr.sbn.getUserId());
2379
2380 assertFalse(posted.getNotification().isColorized());
2381 }
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002382
2383 @Test
2384 public void testGetNotificationCountLocked() throws Exception {
2385 for (int i = 0; i < 20; i++) {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002386 NotificationRecord r =
2387 generateNotificationRecord(mTestNotificationChannel, i, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002388 mService.addEnqueuedNotification(r);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002389 }
2390 for (int i = 0; i < 20; i++) {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002391 NotificationRecord r =
2392 generateNotificationRecord(mTestNotificationChannel, i, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002393 mService.addNotification(r);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002394 }
2395
2396 // another package
2397 Notification n =
2398 new Notification.Builder(mContext, mTestNotificationChannel.getId())
2399 .setSmallIcon(android.R.drawable.sym_def_app_icon)
2400 .build();
2401
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002402 StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "tag", mUid, 0,
2403 n, new UserHandle(mUid), null, 0);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002404 NotificationRecord otherPackage =
2405 new NotificationRecord(mContext, sbn, mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002406 mService.addEnqueuedNotification(otherPackage);
2407 mService.addNotification(otherPackage);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002408
2409 // Same notifications are enqueued as posted, everything counts b/c id and tag don't match
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002410 int userId = new UserHandle(mUid).getIdentifier();
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002411 assertEquals(40,
Julia Reynolds503ed942017-10-04 16:04:56 -04002412 mService.getNotificationCountLocked(PKG, userId, 0, null));
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002413 assertEquals(40,
Julia Reynolds503ed942017-10-04 16:04:56 -04002414 mService.getNotificationCountLocked(PKG, userId, 0, "tag2"));
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002415 assertEquals(2,
Julia Reynolds503ed942017-10-04 16:04:56 -04002416 mService.getNotificationCountLocked("a", userId, 0, "banana"));
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002417
2418 // exclude a known notification - it's excluded from only the posted list, not enqueued
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002419 assertEquals(39,
Julia Reynolds503ed942017-10-04 16:04:56 -04002420 mService.getNotificationCountLocked(PKG, userId, 0, "tag"));
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002421 }
2422
2423 @Test
Julia Reynolds51710712017-07-19 13:48:07 -04002424 public void testAddAutogroup_requestsSort() throws Exception {
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002425 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002426 mService.setRankingHandler(rh);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002427
2428 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002429 mService.addNotification(r);
2430 mService.addAutogroupKeyLocked(r.getKey());
Julia Reynolds51710712017-07-19 13:48:07 -04002431
2432 verify(rh, times(1)).requestSort();
2433 }
2434
2435 @Test
2436 public void testRemoveAutogroup_requestsSort() throws Exception {
2437 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002438 mService.setRankingHandler(rh);
Julia Reynolds51710712017-07-19 13:48:07 -04002439
2440 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2441 r.setOverrideGroupKey("TEST");
Julia Reynolds503ed942017-10-04 16:04:56 -04002442 mService.addNotification(r);
2443 mService.removeAutogroupKeyLocked(r.getKey());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002444
Julia Reynolds51710712017-07-19 13:48:07 -04002445 verify(rh, times(1)).requestSort();
2446 }
2447
2448 @Test
2449 public void testReaddAutogroup_noSort() throws Exception {
2450 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002451 mService.setRankingHandler(rh);
Julia Reynolds51710712017-07-19 13:48:07 -04002452
2453 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2454 r.setOverrideGroupKey("TEST");
Julia Reynolds503ed942017-10-04 16:04:56 -04002455 mService.addNotification(r);
2456 mService.addAutogroupKeyLocked(r.getKey());
Julia Reynolds51710712017-07-19 13:48:07 -04002457
2458 verify(rh, never()).requestSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002459 }
2460
2461 @Test
2462 public void testHandleRankingSort_sendsUpdateOnSignalExtractorChange() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002463 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002464 NotificationManagerService.WorkerHandler handler = mock(
2465 NotificationManagerService.WorkerHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002466 mService.setHandler(handler);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002467
2468 Map<String, Answer> answers = getSignalExtractorSideEffects();
2469 for (String message : answers.keySet()) {
Julia Reynolds503ed942017-10-04 16:04:56 -04002470 mService.clearNotifications();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002471 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002472 mService.addNotification(r);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002473
2474 doAnswer(answers.get(message)).when(mRankingHelper).extractSignals(r);
2475
Julia Reynolds503ed942017-10-04 16:04:56 -04002476 mService.handleRankingSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002477 }
2478 verify(handler, times(answers.size())).scheduleSendRankingUpdate();
2479 }
2480
2481 @Test
2482 public void testHandleRankingSort_noUpdateWhenNoSignalChange() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04002483 mService.setRankingHelper(mRankingHelper);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002484 NotificationManagerService.WorkerHandler handler = mock(
2485 NotificationManagerService.WorkerHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002486 mService.setHandler(handler);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002487
2488 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002489 mService.addNotification(r);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002490
Julia Reynolds503ed942017-10-04 16:04:56 -04002491 mService.handleRankingSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002492 verify(handler, never()).scheduleSendRankingUpdate();
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002493 }
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002494
2495 @Test
2496 public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception {
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002497 final String upgradeXml = "<notification-policy version=\"1\">"
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002498 + "<ranking></ranking>"
2499 + "<enabled_listeners>"
2500 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
2501 + "</enabled_listeners>"
2502 + "<enabled_assistants>"
2503 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
2504 + "</enabled_assistants>"
2505 + "<dnd_apps>"
2506 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
2507 + "</dnd_apps>"
2508 + "</notification-policy>";
Julia Reynolds503ed942017-10-04 16:04:56 -04002509 mService.readPolicyXml(
Annie Meng8b646fd2019-02-01 18:46:42 +00002510 new BufferedInputStream(new ByteArrayInputStream(upgradeXml.getBytes())),
2511 false,
2512 UserHandle.USER_ALL);
2513 verify(mListeners, times(1)).readXml(any(), any(), anyBoolean(), anyInt());
2514 verify(mConditionProviders, times(1)).readXml(any(), any(), anyBoolean(), anyInt());
2515 verify(mAssistants, times(1)).readXml(any(), any(), anyBoolean(), anyInt());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002516
2517 // numbers are inflated for setup
2518 verify(mListeners, times(1)).migrateToXml();
2519 verify(mConditionProviders, times(1)).migrateToXml();
2520 verify(mAssistants, times(1)).migrateToXml();
Fabian Kozynski171f40d2019-02-20 12:53:17 -05002521 verify(mAssistants, never()).ensureAssistant();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002522 }
2523
2524 @Test
2525 public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception {
2526 final String preupgradeXml = "<notification-policy version=\"1\">"
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002527 + "<ranking></ranking>"
2528 + "</notification-policy>";
Julia Reynolds503ed942017-10-04 16:04:56 -04002529 mService.readPolicyXml(
Annie Meng8b646fd2019-02-01 18:46:42 +00002530 new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
2531 false,
2532 UserHandle.USER_ALL);
2533 verify(mListeners, never()).readXml(any(), any(), anyBoolean(), anyInt());
2534 verify(mConditionProviders, never()).readXml(any(), any(), anyBoolean(), anyInt());
2535 verify(mAssistants, never()).readXml(any(), any(), anyBoolean(), anyInt());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002536
2537 // numbers are inflated for setup
2538 verify(mListeners, times(2)).migrateToXml();
2539 verify(mConditionProviders, times(2)).migrateToXml();
2540 verify(mAssistants, times(2)).migrateToXml();
Fabian Kozynski171f40d2019-02-20 12:53:17 -05002541 verify(mAssistants, never()).ensureAssistant();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002542 }
2543
Annie Meng8b646fd2019-02-01 18:46:42 +00002544 @Test
2545 public void testReadPolicyXml_doesNotRestoreManagedServicesForManagedUser() throws Exception {
2546 final String policyXml = "<notification-policy version=\"1\">"
2547 + "<ranking></ranking>"
2548 + "<enabled_listeners>"
2549 + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
2550 + "</enabled_listeners>"
2551 + "<enabled_assistants>"
2552 + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
2553 + "</enabled_assistants>"
2554 + "<dnd_apps>"
2555 + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
2556 + "</dnd_apps>"
2557 + "</notification-policy>";
2558 when(mUserMangerService.isManagedProfile(10)).thenReturn(true);
2559 mService.readPolicyXml(
2560 new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())),
2561 true,
2562 10);
2563 verify(mListeners, never()).readXml(any(), any(), eq(true), eq(10));
2564 verify(mConditionProviders, never()).readXml(any(), any(), eq(true), eq(10));
2565 verify(mAssistants, never()).readXml(any(), any(), eq(true), eq(10));
2566 }
2567
2568 @Test
2569 public void testReadPolicyXml_restoresManagedServicesForNonManagedUser() throws Exception {
2570 final String policyXml = "<notification-policy version=\"1\">"
2571 + "<ranking></ranking>"
2572 + "<enabled_listeners>"
2573 + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
2574 + "</enabled_listeners>"
2575 + "<enabled_assistants>"
2576 + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
2577 + "</enabled_assistants>"
2578 + "<dnd_apps>"
2579 + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
2580 + "</dnd_apps>"
2581 + "</notification-policy>";
2582 when(mUserMangerService.isManagedProfile(10)).thenReturn(false);
2583 mService.readPolicyXml(
2584 new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())),
2585 true,
2586 10);
2587 verify(mListeners, times(1)).readXml(any(), any(), eq(true), eq(10));
2588 verify(mConditionProviders, times(1)).readXml(any(), any(), eq(true), eq(10));
2589 verify(mAssistants, times(1)).readXml(any(), any(), eq(true), eq(10));
2590 }
Beverlyd4f96492017-08-02 13:36:11 -04002591
2592 @Test
2593 public void testLocaleChangedCallsUpdateDefaultZenModeRules() throws Exception {
2594 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002595 mService.mZenModeHelper = mZenModeHelper;
2596 mService.mLocaleChangeReceiver.onReceive(mContext,
Beverlyd4f96492017-08-02 13:36:11 -04002597 new Intent(Intent.ACTION_LOCALE_CHANGED));
2598
2599 verify(mZenModeHelper, times(1)).updateDefaultZenRules();
2600 }
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002601
2602 @Test
2603 public void testBumpFGImportance_noChannelChangePreOApp() throws Exception {
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002604 String preOPkg = PKG_N_MR1;
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002605 final ApplicationInfo legacy = new ApplicationInfo();
2606 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
2607 when(mPackageManagerClient.getApplicationInfoAsUser(eq(preOPkg), anyInt(), anyInt()))
2608 .thenReturn(legacy);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002609 when(mPackageManagerClient.getPackageUidAsUser(eq(preOPkg), anyInt()))
2610 .thenReturn(Binder.getCallingUid());
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002611 getContext().setMockPackageManager(mPackageManagerClient);
2612
2613 Notification.Builder nb = new Notification.Builder(mContext,
2614 NotificationChannel.DEFAULT_CHANNEL_ID)
2615 .setContentTitle("foo")
2616 .setSmallIcon(android.R.drawable.sym_def_app_icon)
Julia Reynoldse5c60452018-04-30 14:41:36 -04002617 .setFlag(FLAG_FOREGROUND_SERVICE, true)
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002618 .setPriority(Notification.PRIORITY_MIN);
2619
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002620 StatusBarNotification sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag",
2621 Binder.getCallingUid(), 0, nb.build(), new UserHandle(Binder.getCallingUid()), null, 0);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002622
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002623 mBinderService.enqueueNotificationWithTag(sbn.getPackageName(), sbn.getOpPkg(),
2624 sbn.getTag(), sbn.getId(), sbn.getNotification(), sbn.getUserId());
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002625 waitForIdle();
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002626
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002627 assertEquals(IMPORTANCE_LOW,
Julia Reynolds503ed942017-10-04 16:04:56 -04002628 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002629
2630 nb = new Notification.Builder(mContext)
2631 .setContentTitle("foo")
2632 .setSmallIcon(android.R.drawable.sym_def_app_icon)
Julia Reynoldse5c60452018-04-30 14:41:36 -04002633 .setFlag(FLAG_FOREGROUND_SERVICE, true)
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002634 .setPriority(Notification.PRIORITY_MIN);
2635
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04002636 sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", Binder.getCallingUid(),
2637 0, nb.build(), new UserHandle(Binder.getCallingUid()), null, 0);
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002638
2639 mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag",
2640 sbn.getId(), sbn.getNotification(), sbn.getUserId());
2641 waitForIdle();
2642 assertEquals(IMPORTANCE_LOW,
Julia Reynolds503ed942017-10-04 16:04:56 -04002643 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002644
2645 NotificationChannel defaultChannel = mBinderService.getNotificationChannel(
2646 preOPkg, NotificationChannel.DEFAULT_CHANNEL_ID);
2647 assertEquals(IMPORTANCE_UNSPECIFIED, defaultChannel.getImportance());
2648 }
Julia Reynolds503ed942017-10-04 16:04:56 -04002649
2650 @Test
2651 public void testStats_updatedOnDirectReply() throws Exception {
2652 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2653 mService.addNotification(r);
2654
2655 mService.mNotificationDelegate.onNotificationDirectReplied(r.getKey());
2656 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasDirectReplied());
Tony Makeda84a72018-11-19 17:01:32 +00002657 verify(mAssistants).notifyAssistantNotificationDirectReplyLocked(eq(r.sbn));
Julia Reynolds503ed942017-10-04 16:04:56 -04002658 }
2659
2660 @Test
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002661 public void testStats_updatedOnUserExpansion() throws Exception {
2662 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002663 mService.addNotification(r);
2664
Gustav Senntona8e38aa2019-01-22 14:55:39 +00002665 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), true, true,
2666 NOTIFICATION_LOCATION_UNKNOWN);
Tony Makeda84a72018-11-19 17:01:32 +00002667 verify(mAssistants).notifyAssistantExpansionChangedLocked(eq(r.sbn), eq(true), eq((true)));
Julia Reynolds503ed942017-10-04 16:04:56 -04002668 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
Tony Makeda84a72018-11-19 17:01:32 +00002669
Gustav Senntona8e38aa2019-01-22 14:55:39 +00002670 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), true, false,
2671 NOTIFICATION_LOCATION_UNKNOWN);
Tony Makeda84a72018-11-19 17:01:32 +00002672 verify(mAssistants).notifyAssistantExpansionChangedLocked(eq(r.sbn), eq(true), eq((false)));
Julia Reynolds503ed942017-10-04 16:04:56 -04002673 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
2674 }
2675
2676 @Test
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002677 public void testStats_notUpdatedOnAutoExpansion() throws Exception {
2678 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2679 mService.addNotification(r);
2680
Gustav Senntona8e38aa2019-01-22 14:55:39 +00002681 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, true,
2682 NOTIFICATION_LOCATION_UNKNOWN);
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002683 assertFalse(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
Tony Makeda84a72018-11-19 17:01:32 +00002684 verify(mAssistants).notifyAssistantExpansionChangedLocked(eq(r.sbn), eq(false), eq((true)));
2685
Gustav Senntona8e38aa2019-01-22 14:55:39 +00002686 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, false,
2687 NOTIFICATION_LOCATION_UNKNOWN);
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002688 assertFalse(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
Tony Makeda84a72018-11-19 17:01:32 +00002689 verify(mAssistants).notifyAssistantExpansionChangedLocked(
2690 eq(r.sbn), eq(false), eq((false)));
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002691 }
2692
2693 @Test
Julia Reynolds503ed942017-10-04 16:04:56 -04002694 public void testStats_updatedOnViewSettings() throws Exception {
2695 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2696 mService.addNotification(r);
2697
2698 mService.mNotificationDelegate.onNotificationSettingsViewed(r.getKey());
2699 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasViewedSettings());
2700 }
2701
2702 @Test
2703 public void testStats_updatedOnVisibilityChanged() throws Exception {
2704 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2705 mService.addNotification(r);
2706
Dieter Hsud39f0d52018-04-14 02:08:30 +08002707 final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 1, 2, true);
Julia Reynolds503ed942017-10-04 16:04:56 -04002708 mService.mNotificationDelegate.onNotificationVisibilityChanged(
2709 new NotificationVisibility[] {nv}, new NotificationVisibility[]{});
2710 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasSeen());
2711 mService.mNotificationDelegate.onNotificationVisibilityChanged(
2712 new NotificationVisibility[] {}, new NotificationVisibility[]{nv});
2713 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasSeen());
2714 }
2715
2716 @Test
2717 public void testStats_dismissalSurface() throws Exception {
2718 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2719 mService.addNotification(r);
2720
Dieter Hsud39f0d52018-04-14 02:08:30 +08002721 final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
Julia Reynolds503ed942017-10-04 16:04:56 -04002722 mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.sbn.getTag(),
Julia Reynoldsfd4099d2018-08-21 11:06:06 -04002723 r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD,
2724 NotificationStats.DISMISS_SENTIMENT_POSITIVE, nv);
Julia Reynolds503ed942017-10-04 16:04:56 -04002725 waitForIdle();
2726
2727 assertEquals(NotificationStats.DISMISSAL_AOD, r.getStats().getDismissalSurface());
2728 }
2729
2730 @Test
Julia Reynoldsfd4099d2018-08-21 11:06:06 -04002731 public void testStats_dismissalSentiment() throws Exception {
2732 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2733 mService.addNotification(r);
2734
2735 final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
2736 mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.sbn.getTag(),
2737 r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD,
2738 NotificationStats.DISMISS_SENTIMENT_NEGATIVE, nv);
2739 waitForIdle();
2740
2741 assertEquals(NotificationStats.DISMISS_SENTIMENT_NEGATIVE,
2742 r.getStats().getDismissalSentiment());
2743 }
2744
2745 @Test
Julia Reynolds70aaea72018-07-13 13:38:34 -04002746 public void testApplyAdjustmentMultiUser() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04002747 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2748 mService.addNotification(r);
2749 NotificationManagerService.WorkerHandler handler = mock(
2750 NotificationManagerService.WorkerHandler.class);
2751 mService.setHandler(handler);
2752
Julia Reynolds70aaea72018-07-13 13:38:34 -04002753 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(false);
2754
Julia Reynolds503ed942017-10-04 16:04:56 -04002755 Bundle signals = new Bundle();
2756 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
Julia Reynolds70aaea72018-07-13 13:38:34 -04002757 USER_SENTIMENT_NEGATIVE);
2758 Adjustment adjustment = new Adjustment(
2759 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2760 mBinderService.applyAdjustmentFromAssistant(null, adjustment);
2761
2762 waitForIdle();
2763
2764 verify(handler, timeout(300).times(0)).scheduleSendRankingUpdate();
2765 }
2766
2767 @Test
Julia Reynolds27c0a962018-12-10 12:37:28 -05002768 public void testAssistantBlockingTriggersCancel() throws Exception {
Julia Reynoldsefcdff42018-08-09 09:42:56 -04002769 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2770 mService.addNotification(r);
2771 NotificationManagerService.WorkerHandler handler = mock(
2772 NotificationManagerService.WorkerHandler.class);
2773 mService.setHandler(handler);
2774
2775 Bundle signals = new Bundle();
2776 signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE);
2777 Adjustment adjustment = new Adjustment(
2778 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2779 when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
2780 mBinderService.applyAdjustmentFromAssistant(null, adjustment);
2781
2782 waitForIdle();
2783
2784 verify(handler, timeout(300).times(0)).scheduleSendRankingUpdate();
2785 verify(handler, times(1)).scheduleCancelNotification(any());
2786 }
2787
2788 @Test
Julia Reynolds70aaea72018-07-13 13:38:34 -04002789 public void testApplyEnqueuedAdjustmentFromAssistant_singleUser() throws Exception {
2790 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2791 mService.addEnqueuedNotification(r);
2792 NotificationManagerService.WorkerHandler handler = mock(
2793 NotificationManagerService.WorkerHandler.class);
2794 mService.setHandler(handler);
2795 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
2796
2797 Bundle signals = new Bundle();
2798 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
2799 USER_SENTIMENT_NEGATIVE);
2800 Adjustment adjustment = new Adjustment(
2801 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2802 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
2803
2804 assertEquals(USER_SENTIMENT_NEGATIVE, r.getUserSentiment());
2805 }
2806
2807 @Test
Julia Reynolds27c0a962018-12-10 12:37:28 -05002808 public void testApplyEnqueuedAdjustmentFromAssistant_importance_onTime() throws Exception {
2809 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2810 mService.addEnqueuedNotification(r);
2811 NotificationManagerService.WorkerHandler handler = mock(
2812 NotificationManagerService.WorkerHandler.class);
2813 mService.setHandler(handler);
2814 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
2815
2816 Bundle signals = new Bundle();
2817 signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
2818 Adjustment adjustment = new Adjustment(
2819 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2820 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
2821
2822 assertEquals(IMPORTANCE_LOW, r.getImportance());
2823 }
2824
2825 @Test
2826 public void testApplyEnqueuedAdjustmentFromAssistant_importance_tooLate() throws Exception {
2827 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2828 mService.addNotification(r);
2829 NotificationManagerService.WorkerHandler handler = mock(
2830 NotificationManagerService.WorkerHandler.class);
2831 mService.setHandler(handler);
2832 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
2833
2834 Bundle signals = new Bundle();
2835 signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
2836 Adjustment adjustment = new Adjustment(
2837 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2838 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
2839
2840 assertEquals(IMPORTANCE_DEFAULT, r.getImportance());
2841 assertFalse(r.hasAdjustment(Adjustment.KEY_IMPORTANCE));
2842 }
2843
2844 @Test
Julia Reynolds70aaea72018-07-13 13:38:34 -04002845 public void testApplyEnqueuedAdjustmentFromAssistant_crossUser() throws Exception {
2846 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2847 mService.addEnqueuedNotification(r);
2848 NotificationManagerService.WorkerHandler handler = mock(
2849 NotificationManagerService.WorkerHandler.class);
2850 mService.setHandler(handler);
2851 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(false);
2852
2853 Bundle signals = new Bundle();
2854 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
2855 USER_SENTIMENT_NEGATIVE);
2856 Adjustment adjustment = new Adjustment(
2857 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2858 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
2859
2860 assertEquals(USER_SENTIMENT_NEUTRAL, r.getUserSentiment());
2861
2862 waitForIdle();
2863
2864 verify(handler, timeout(300).times(0)).scheduleSendRankingUpdate();
2865 }
2866
2867 @Test
2868 public void testUserSentimentChangeTriggersUpdate() throws Exception {
2869 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2870 mService.addNotification(r);
2871 NotificationManagerService.WorkerHandler handler = mock(
2872 NotificationManagerService.WorkerHandler.class);
2873 mService.setHandler(handler);
2874 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
2875
2876 Bundle signals = new Bundle();
2877 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
2878 USER_SENTIMENT_NEGATIVE);
Julia Reynolds503ed942017-10-04 16:04:56 -04002879 Adjustment adjustment = new Adjustment(
2880 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2881 mBinderService.applyAdjustmentFromAssistant(null, adjustment);
2882
2883 waitForIdle();
2884
2885 verify(handler, timeout(300).times(1)).scheduleSendRankingUpdate();
2886 }
Julia Reynolds7bcb57b2018-01-22 10:37:58 -05002887
2888 @Test
Julia Reynolds666ccf02018-06-18 10:19:20 -04002889 public void testTooLateAdjustmentTriggersUpdate() throws Exception {
2890 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2891 mService.addNotification(r);
2892 NotificationManagerService.WorkerHandler handler = mock(
2893 NotificationManagerService.WorkerHandler.class);
2894 mService.setHandler(handler);
Julia Reynolds70aaea72018-07-13 13:38:34 -04002895 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
Julia Reynolds666ccf02018-06-18 10:19:20 -04002896
2897 Bundle signals = new Bundle();
2898 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
Julia Reynolds70aaea72018-07-13 13:38:34 -04002899 USER_SENTIMENT_NEGATIVE);
Julia Reynolds666ccf02018-06-18 10:19:20 -04002900 Adjustment adjustment = new Adjustment(
2901 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2902 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
2903
2904 waitForIdle();
2905
2906 verify(handler, timeout(300).times(1)).scheduleSendRankingUpdate();
2907 }
2908
2909 @Test
2910 public void testEnqueuedAdjustmentAppliesAdjustments() throws Exception {
2911 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2912 mService.addEnqueuedNotification(r);
2913 NotificationManagerService.WorkerHandler handler = mock(
2914 NotificationManagerService.WorkerHandler.class);
2915 mService.setHandler(handler);
Julia Reynolds70aaea72018-07-13 13:38:34 -04002916 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
Julia Reynolds666ccf02018-06-18 10:19:20 -04002917
2918 Bundle signals = new Bundle();
2919 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
Julia Reynolds70aaea72018-07-13 13:38:34 -04002920 USER_SENTIMENT_NEGATIVE);
Julia Reynolds666ccf02018-06-18 10:19:20 -04002921 Adjustment adjustment = new Adjustment(
2922 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2923 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
2924
Julia Reynolds70aaea72018-07-13 13:38:34 -04002925 assertEquals(USER_SENTIMENT_NEGATIVE,
Julia Reynolds666ccf02018-06-18 10:19:20 -04002926 r.getUserSentiment());
2927 }
2928
2929 @Test
Julia Reynolds7bcb57b2018-01-22 10:37:58 -05002930 public void testRecents() throws Exception {
2931 Set<NotifyingApp> expected = new HashSet<>();
2932
2933 final NotificationRecord oldest = new NotificationRecord(mContext,
2934 generateSbn("p", 1000, 9, 0), mTestNotificationChannel);
2935 mService.logRecentLocked(oldest);
2936 for (int i = 1; i <= 5; i++) {
2937 NotificationRecord r = new NotificationRecord(mContext,
2938 generateSbn("p" + i, i, i*100, 0), mTestNotificationChannel);
2939 expected.add(new NotifyingApp()
2940 .setPackage(r.sbn.getPackageName())
2941 .setUid(r.sbn.getUid())
2942 .setLastNotified(r.sbn.getPostTime()));
2943 mService.logRecentLocked(r);
2944 }
2945
2946 List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
2947 assertTrue(apps.size() == 5);
2948 for (NotifyingApp actual : apps) {
2949 assertTrue("got unexpected result: " + actual, expected.contains(actual));
2950 }
2951 }
2952
2953 @Test
2954 public void testRecentsNoDuplicatePackages() throws Exception {
2955 final NotificationRecord p1 = new NotificationRecord(mContext, generateSbn("p", 1, 1000, 0),
2956 mTestNotificationChannel);
2957 final NotificationRecord p2 = new NotificationRecord(mContext, generateSbn("p", 1, 2000, 0),
2958 mTestNotificationChannel);
2959
2960 mService.logRecentLocked(p1);
2961 mService.logRecentLocked(p2);
2962
2963 List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
2964 assertTrue(apps.size() == 1);
2965 NotifyingApp expected = new NotifyingApp().setPackage("p").setUid(1).setLastNotified(2000);
2966 assertEquals(expected, apps.get(0));
2967 }
2968
2969 @Test
2970 public void testRecentsWithDuplicatePackage() throws Exception {
2971 Set<NotifyingApp> expected = new HashSet<>();
2972
2973 final NotificationRecord oldest = new NotificationRecord(mContext,
2974 generateSbn("p", 1000, 9, 0), mTestNotificationChannel);
2975 mService.logRecentLocked(oldest);
2976 for (int i = 1; i <= 5; i++) {
2977 NotificationRecord r = new NotificationRecord(mContext,
2978 generateSbn("p" + i, i, i*100, 0), mTestNotificationChannel);
2979 expected.add(new NotifyingApp()
2980 .setPackage(r.sbn.getPackageName())
2981 .setUid(r.sbn.getUid())
2982 .setLastNotified(r.sbn.getPostTime()));
2983 mService.logRecentLocked(r);
2984 }
2985 NotificationRecord r = new NotificationRecord(mContext,
2986 generateSbn("p" + 3, 3, 300000, 0), mTestNotificationChannel);
2987 expected.remove(new NotifyingApp()
2988 .setPackage(r.sbn.getPackageName())
2989 .setUid(3)
2990 .setLastNotified(300));
2991 NotifyingApp newest = new NotifyingApp()
2992 .setPackage(r.sbn.getPackageName())
2993 .setUid(r.sbn.getUid())
2994 .setLastNotified(r.sbn.getPostTime());
2995 expected.add(newest);
2996 mService.logRecentLocked(r);
2997
2998 List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
2999 assertTrue(apps.size() == 5);
3000 for (NotifyingApp actual : apps) {
3001 assertTrue("got unexpected result: " + actual, expected.contains(actual));
3002 }
3003 assertEquals(newest, apps.get(0));
3004 }
3005
3006 @Test
3007 public void testRecentsMultiuser() throws Exception {
3008 final NotificationRecord user1 = new NotificationRecord(mContext,
3009 generateSbn("p", 1000, 9, 1), mTestNotificationChannel);
3010 mService.logRecentLocked(user1);
3011
3012 final NotificationRecord user2 = new NotificationRecord(mContext,
3013 generateSbn("p2", 100000, 9999, 2), mTestNotificationChannel);
3014 mService.logRecentLocked(user2);
3015
3016 assertEquals(0, mBinderService.getRecentNotifyingAppsForUser(0).getList().size());
3017 assertEquals(1, mBinderService.getRecentNotifyingAppsForUser(1).getList().size());
3018 assertEquals(1, mBinderService.getRecentNotifyingAppsForUser(2).getList().size());
3019
3020 assertTrue(mBinderService.getRecentNotifyingAppsForUser(2).getList().contains(
3021 new NotifyingApp()
3022 .setPackage(user2.sbn.getPackageName())
3023 .setUid(user2.sbn.getUid())
3024 .setLastNotified(user2.sbn.getPostTime())));
3025 }
Julia Reynoldsd78263d2018-01-30 10:40:41 -05003026
3027 @Test
3028 public void testRestore() throws Exception {
3029 int systemChecks = mService.countSystemChecks;
3030 mBinderService.applyRestore(null, UserHandle.USER_SYSTEM);
3031 assertEquals(1, mService.countSystemChecks - systemChecks);
3032 }
3033
3034 @Test
3035 public void testBackup() throws Exception {
3036 int systemChecks = mService.countSystemChecks;
3037 mBinderService.getBackupPayload(1);
3038 assertEquals(1, mService.countSystemChecks - systemChecks);
3039 }
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003040
3041 @Test
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003042 public void updateUriPermissions_update() throws Exception {
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003043 NotificationChannel c = new NotificationChannel(
Julia Reynolds27c0a962018-12-10 12:37:28 -05003044 TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003045 c.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
3046 Message message1 = new Message("", 0, "");
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003047 message1.setData("",
3048 ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1));
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003049 Message message2 = new Message("", 1, "");
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003050 message2.setData("",
3051 ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 2));
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003052
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003053 Notification.Builder nbA = new Notification.Builder(mContext, c.getId())
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003054 .setContentTitle("foo")
3055 .setSmallIcon(android.R.drawable.sym_def_app_icon)
3056 .setStyle(new Notification.MessagingStyle("")
3057 .addMessage(message1)
3058 .addMessage(message2));
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003059 NotificationRecord recordA = new NotificationRecord(mContext, new StatusBarNotification(
3060 PKG, PKG, 0, "tag", mUid, 0, nbA.build(), new UserHandle(mUid), null, 0), c);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003061
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003062 // First post means we grant access to both
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003063 reset(mUgm);
3064 reset(mUgmInternal);
3065 when(mUgmInternal.newUriPermissionOwner(any())).thenReturn(new Binder());
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003066 mService.updateUriPermissions(recordA, null, mContext.getPackageName(),
3067 UserHandle.USER_SYSTEM);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003068 verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003069 eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003070 verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003071 eq(message2.getDataUri()), anyInt(), anyInt(), anyInt());
3072
3073 Notification.Builder nbB = new Notification.Builder(mContext, c.getId())
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003074 .setContentTitle("foo")
3075 .setSmallIcon(android.R.drawable.sym_def_app_icon)
3076 .setStyle(new Notification.MessagingStyle("").addMessage(message2));
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003077 NotificationRecord recordB = new NotificationRecord(mContext, new StatusBarNotification(PKG,
3078 PKG, 0, "tag", mUid, 0, nbB.build(), new UserHandle(mUid), null, 0), c);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003079
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003080 // Update means we drop access to first
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003081 reset(mUgmInternal);
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003082 mService.updateUriPermissions(recordB, recordA, mContext.getPackageName(),
3083 UserHandle.USER_SYSTEM);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003084 verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(),
3085 eq(message1.getDataUri()), anyInt(), anyInt());
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003086
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003087 // Update back means we grant access to first again
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003088 reset(mUgm);
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003089 mService.updateUriPermissions(recordA, recordB, mContext.getPackageName(),
3090 UserHandle.USER_SYSTEM);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003091 verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003092 eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003093
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003094 // And update to empty means we drop everything
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003095 reset(mUgmInternal);
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06003096 mService.updateUriPermissions(null, recordB, mContext.getPackageName(),
3097 UserHandle.USER_SYSTEM);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003098 verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(), eq(null),
Julia Reynoldse0d711f2017-09-01 08:50:47 -04003099 anyInt(), anyInt());
3100 }
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05003101
3102 @Test
Robin Leed107af62018-04-27 13:55:56 +02003103 public void testVisitUris() throws Exception {
3104 final Uri audioContents = Uri.parse("content://com.example/audio");
3105 final Uri backgroundImage = Uri.parse("content://com.example/background");
3106
3107 Bundle extras = new Bundle();
3108 extras.putParcelable(Notification.EXTRA_AUDIO_CONTENTS_URI, audioContents);
3109 extras.putString(Notification.EXTRA_BACKGROUND_IMAGE_URI, backgroundImage.toString());
3110
3111 Notification n = new Notification.Builder(mContext, "a")
3112 .setContentTitle("notification with uris")
3113 .setSmallIcon(android.R.drawable.sym_def_app_icon)
3114 .addExtras(extras)
3115 .build();
3116
3117 Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
3118 n.visitUris(visitor);
3119 verify(visitor, times(1)).accept(eq(audioContents));
3120 verify(visitor, times(1)).accept(eq(backgroundImage));
3121 }
3122
3123 @Test
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05003124 public void testSetNotificationPolicy_preP_setOldFields() {
3125 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
3126 mService.mZenModeHelper = mZenModeHelper;
3127 NotificationManager.Policy userPolicy =
3128 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
3129 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
3130
3131 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
3132 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF);
3133
3134 int expected = SUPPRESSED_EFFECT_BADGE
3135 | SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF
Julia Reynoldseac2da22018-04-12 10:48:46 -04003136 | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_LIGHTS
3137 | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05003138 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
3139
3140 assertEquals(expected, actual);
3141 }
3142
3143 @Test
3144 public void testSetNotificationPolicy_preP_setNewFields() {
3145 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
3146 mService.mZenModeHelper = mZenModeHelper;
3147 NotificationManager.Policy userPolicy =
3148 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
3149 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
3150
3151 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
3152 SUPPRESSED_EFFECT_NOTIFICATION_LIST);
3153
3154 int expected = SUPPRESSED_EFFECT_BADGE;
3155 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
3156
3157 assertEquals(expected, actual);
3158 }
3159
3160 @Test
3161 public void testSetNotificationPolicy_preP_setOldNewFields() {
3162 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
3163 mService.mZenModeHelper = mZenModeHelper;
3164 NotificationManager.Policy userPolicy =
3165 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
3166 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
3167
3168 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
3169 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_STATUS_BAR);
3170
3171 int expected =
3172 SUPPRESSED_EFFECT_BADGE | SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_PEEK;
3173 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
3174
3175 assertEquals(expected, actual);
3176 }
3177
3178 @Test
3179 public void testSetNotificationPolicy_P_setOldFields() {
3180 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
3181 mService.mZenModeHelper = mZenModeHelper;
3182 NotificationManager.Policy userPolicy =
3183 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
3184 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
3185
3186 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
3187 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF);
3188
3189 int expected = SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF
3190 | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_AMBIENT
3191 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
3192 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
3193
3194 assertEquals(expected, actual);
3195 }
3196
3197 @Test
3198 public void testSetNotificationPolicy_P_setNewFields() {
3199 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
3200 mService.mZenModeHelper = mZenModeHelper;
3201 NotificationManager.Policy userPolicy =
3202 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
3203 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
3204
3205 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
3206 SUPPRESSED_EFFECT_NOTIFICATION_LIST | SUPPRESSED_EFFECT_AMBIENT
3207 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT);
3208
3209 int expected = SUPPRESSED_EFFECT_NOTIFICATION_LIST | SUPPRESSED_EFFECT_SCREEN_OFF
3210 | SUPPRESSED_EFFECT_AMBIENT | SUPPRESSED_EFFECT_LIGHTS
3211 | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
3212 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
3213
3214 assertEquals(expected, actual);
3215 }
3216
3217 @Test
3218 public void testSetNotificationPolicy_P_setOldNewFields() {
3219 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
3220 mService.mZenModeHelper = mZenModeHelper;
3221 NotificationManager.Policy userPolicy =
3222 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
3223 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
3224
3225 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
3226 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_STATUS_BAR);
3227
3228 int expected = SUPPRESSED_EFFECT_STATUS_BAR;
3229 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
3230
3231 assertEquals(expected, actual);
3232
3233 appPolicy = new NotificationManager.Policy(0, 0, 0,
3234 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_AMBIENT
3235 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT);
3236
3237 expected = SUPPRESSED_EFFECT_SCREEN_OFF | SUPPRESSED_EFFECT_AMBIENT
3238 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
3239 actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
3240
3241 assertEquals(expected, actual);
3242 }
Julia Reynolds7217dc92018-03-07 12:12:09 -05003243
3244 @Test
Julia Reynoldse5c60452018-04-30 14:41:36 -04003245 public void testVisualDifference_foreground() {
3246 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3247 .setContentTitle("foo");
3248 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3249 nb1.build(), new UserHandle(mUid), null, 0);
3250 NotificationRecord r1 =
3251 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3252
3253 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3254 .setFlag(FLAG_FOREGROUND_SERVICE, true)
3255 .setContentTitle("bar");
3256 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3257 nb2.build(), new UserHandle(mUid), null, 0);
3258 NotificationRecord r2 =
3259 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3260
3261 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3262 }
3263
3264 @Test
Julia Reynolds7217dc92018-03-07 12:12:09 -05003265 public void testVisualDifference_diffTitle() {
3266 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3267 .setContentTitle("foo");
3268 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3269 nb1.build(), new UserHandle(mUid), null, 0);
3270 NotificationRecord r1 =
3271 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3272
3273 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3274 .setContentTitle("bar");
3275 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3276 nb2.build(), new UserHandle(mUid), null, 0);
3277 NotificationRecord r2 =
3278 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3279
3280 assertTrue(mService.isVisuallyInterruptive(r1, r2));
3281 }
3282
3283 @Test
Dan Sandler7d67bd42018-05-15 14:06:38 -04003284 public void testVisualDifference_inboxStyle() {
3285 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3286 .setStyle(new Notification.InboxStyle()
3287 .addLine("line1").addLine("line2"));
3288 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3289 nb1.build(), new UserHandle(mUid), null, 0);
3290 NotificationRecord r1 =
3291 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3292
3293 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3294 .setStyle(new Notification.InboxStyle()
3295 .addLine("line1").addLine("line2_changed"));
3296 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3297 nb2.build(), new UserHandle(mUid), null, 0);
3298 NotificationRecord r2 =
3299 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3300
3301 assertTrue(mService.isVisuallyInterruptive(r1, r2)); // line 2 changed unnoticed
3302
3303 Notification.Builder nb3 = new Notification.Builder(mContext, "")
3304 .setStyle(new Notification.InboxStyle()
3305 .addLine("line1"));
3306 StatusBarNotification sbn3 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3307 nb3.build(), new UserHandle(mUid), null, 0);
3308 NotificationRecord r3 =
3309 new NotificationRecord(mContext, sbn3, mock(NotificationChannel.class));
3310
3311 assertTrue(mService.isVisuallyInterruptive(r1, r3)); // line 2 removed unnoticed
3312
3313 Notification.Builder nb4 = new Notification.Builder(mContext, "")
3314 .setStyle(new Notification.InboxStyle()
3315 .addLine("line1").addLine("line2").addLine("line3"));
3316 StatusBarNotification sbn4 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3317 nb4.build(), new UserHandle(mUid), null, 0);
3318 NotificationRecord r4 =
3319 new NotificationRecord(mContext, sbn4, mock(NotificationChannel.class));
3320
3321 assertTrue(mService.isVisuallyInterruptive(r1, r4)); // line 3 added unnoticed
3322
3323 Notification.Builder nb5 = new Notification.Builder(mContext, "")
3324 .setContentText("not an inbox");
3325 StatusBarNotification sbn5 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3326 nb5.build(), new UserHandle(mUid), null, 0);
3327 NotificationRecord r5 =
3328 new NotificationRecord(mContext, sbn5, mock(NotificationChannel.class));
3329
3330 assertTrue(mService.isVisuallyInterruptive(r1, r5)); // changed Styles, went unnoticed
3331 }
3332
3333 @Test
Julia Reynolds7217dc92018-03-07 12:12:09 -05003334 public void testVisualDifference_diffText() {
3335 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3336 .setContentText("foo");
3337 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3338 nb1.build(), new UserHandle(mUid), null, 0);
3339 NotificationRecord r1 =
3340 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3341
3342 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3343 .setContentText("bar");
3344 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3345 nb2.build(), new UserHandle(mUid), null, 0);
3346 NotificationRecord r2 =
3347 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3348
3349 assertTrue(mService.isVisuallyInterruptive(r1, r2));
3350 }
3351
3352 @Test
Dan Sandler7d67bd42018-05-15 14:06:38 -04003353 public void testVisualDifference_sameText() {
3354 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3355 .setContentText("foo");
3356 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3357 nb1.build(), new UserHandle(mUid), null, 0);
3358 NotificationRecord r1 =
3359 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3360
3361 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3362 .setContentText("foo");
3363 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3364 nb2.build(), new UserHandle(mUid), null, 0);
3365 NotificationRecord r2 =
3366 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3367
3368 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3369 }
3370
3371 @Test
3372 public void testVisualDifference_sameTextButStyled() {
3373 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3374 .setContentText(Html.fromHtml("<b>foo</b>"));
3375 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3376 nb1.build(), new UserHandle(mUid), null, 0);
3377 NotificationRecord r1 =
3378 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3379
3380 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3381 .setContentText(Html.fromHtml("<b>foo</b>"));
3382 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3383 nb2.build(), new UserHandle(mUid), null, 0);
3384 NotificationRecord r2 =
3385 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3386
3387 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3388 }
3389
3390 @Test
3391 public void testVisualDifference_diffTextButStyled() {
3392 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3393 .setContentText(Html.fromHtml("<b>foo</b>"));
3394 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3395 nb1.build(), new UserHandle(mUid), null, 0);
3396 NotificationRecord r1 =
3397 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3398
3399 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3400 .setContentText(Html.fromHtml("<b>bar</b>"));
3401 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3402 nb2.build(), new UserHandle(mUid), null, 0);
3403 NotificationRecord r2 =
3404 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3405
3406 assertTrue(mService.isVisuallyInterruptive(r1, r2));
3407 }
3408
3409 @Test
Julia Reynolds7217dc92018-03-07 12:12:09 -05003410 public void testVisualDifference_diffProgress() {
3411 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3412 .setProgress(100, 90, false);
3413 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3414 nb1.build(), new UserHandle(mUid), null, 0);
3415 NotificationRecord r1 =
3416 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3417
3418 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3419 .setProgress(100, 100, false);
3420 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3421 nb2.build(), new UserHandle(mUid), null, 0);
3422 NotificationRecord r2 =
3423 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3424
3425 assertTrue(mService.isVisuallyInterruptive(r1, r2));
3426 }
3427
3428 @Test
3429 public void testVisualDifference_diffProgressNotDone() {
3430 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3431 .setProgress(100, 90, false);
3432 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3433 nb1.build(), new UserHandle(mUid), null, 0);
3434 NotificationRecord r1 =
3435 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3436
3437 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3438 .setProgress(100, 91, false);
3439 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3440 nb2.build(), new UserHandle(mUid), null, 0);
3441 NotificationRecord r2 =
3442 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3443
3444 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3445 }
Beverly5a20a5e2018-03-06 15:02:44 -05003446
3447 @Test
Dan Sandler7d67bd42018-05-15 14:06:38 -04003448 public void testVisualDifference_sameProgressStillDone() {
3449 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3450 .setProgress(100, 100, false);
3451 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3452 nb1.build(), new UserHandle(mUid), null, 0);
3453 NotificationRecord r1 =
3454 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3455
3456 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3457 .setProgress(100, 100, false);
3458 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3459 nb2.build(), new UserHandle(mUid), null, 0);
3460 NotificationRecord r2 =
3461 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3462
3463 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3464 }
3465
3466 @Test
Julia Reynoldsa4fb9da2018-06-04 12:27:58 -04003467 public void testVisualDifference_summary() {
3468 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3469 .setGroup("bananas")
3470 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
3471 .setContentText("foo");
3472 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3473 nb1.build(), new UserHandle(mUid), null, 0);
3474 NotificationRecord r1 =
3475 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3476
3477 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3478 .setGroup("bananas")
3479 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
3480 .setContentText("bar");
3481 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3482 nb2.build(), new UserHandle(mUid), null, 0);
3483 NotificationRecord r2 =
3484 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3485
3486 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3487 }
3488
3489 @Test
Julia Reynolds760fa762018-06-19 15:39:23 -04003490 public void testVisualDifference_summaryNewNotification() {
3491 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3492 .setGroup("bananas")
3493 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
3494 .setContentText("bar");
3495 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3496 nb2.build(), new UserHandle(mUid), null, 0);
3497 NotificationRecord r2 =
3498 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3499
3500 assertFalse(mService.isVisuallyInterruptive(null, r2));
3501 }
3502
3503 @Test
Beverly5a20a5e2018-03-06 15:02:44 -05003504 public void testHideAndUnhideNotificationsOnSuspendedPackageBroadcast() {
3505 // post 2 notification from this package
3506 final NotificationRecord notif1 = generateNotificationRecord(
3507 mTestNotificationChannel, 1, null, true);
3508 final NotificationRecord notif2 = generateNotificationRecord(
3509 mTestNotificationChannel, 2, null, false);
3510 mService.addNotification(notif1);
3511 mService.addNotification(notif2);
3512
3513 // on broadcast, hide the 2 notifications
3514 mService.simulatePackageSuspendBroadcast(true, PKG);
3515 ArgumentCaptor<List> captorHide = ArgumentCaptor.forClass(List.class);
3516 verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
3517 assertEquals(2, captorHide.getValue().size());
3518
3519 // on broadcast, unhide the 2 notifications
3520 mService.simulatePackageSuspendBroadcast(false, PKG);
3521 ArgumentCaptor<List> captorUnhide = ArgumentCaptor.forClass(List.class);
3522 verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
3523 assertEquals(2, captorUnhide.getValue().size());
3524 }
3525
3526 @Test
3527 public void testNoNotificationsHiddenOnSuspendedPackageBroadcast() {
3528 // post 2 notification from this package
3529 final NotificationRecord notif1 = generateNotificationRecord(
3530 mTestNotificationChannel, 1, null, true);
3531 final NotificationRecord notif2 = generateNotificationRecord(
3532 mTestNotificationChannel, 2, null, false);
3533 mService.addNotification(notif1);
3534 mService.addNotification(notif2);
3535
3536 // on broadcast, nothing is hidden since no notifications are of package "test_package"
3537 mService.simulatePackageSuspendBroadcast(true, "test_package");
3538 ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
3539 verify(mListeners, times(1)).notifyHiddenLocked(captor.capture());
3540 assertEquals(0, captor.getValue().size());
3541 }
Kristian Monsen05f34792018-04-09 10:27:16 +02003542
3543 @Test
Julia Reynolds0e5a3432019-01-17 09:40:46 -05003544 public void testHideAndUnhideNotificationsOnDistractingPackageBroadcast() {
3545 // Post 2 notifications from 2 packages
3546 NotificationRecord pkgA = new NotificationRecord(mContext,
3547 generateSbn("a", 1000, 9, 0), mTestNotificationChannel);
3548 mService.addNotification(pkgA);
3549 NotificationRecord pkgB = new NotificationRecord(mContext,
3550 generateSbn("b", 1001, 9, 0), mTestNotificationChannel);
3551 mService.addNotification(pkgB);
3552
3553 // on broadcast, hide one of the packages
3554 mService.simulatePackageDistractionBroadcast(
3555 PackageManager.RESTRICTION_HIDE_NOTIFICATIONS, new String[] {"a"});
3556 ArgumentCaptor<List<NotificationRecord>> captorHide = ArgumentCaptor.forClass(List.class);
3557 verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
3558 assertEquals(1, captorHide.getValue().size());
3559 assertEquals("a", captorHide.getValue().get(0).sbn.getPackageName());
3560
3561 // on broadcast, unhide the package
3562 mService.simulatePackageDistractionBroadcast(
3563 PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS, new String[] {"a"});
3564 ArgumentCaptor<List<NotificationRecord>> captorUnhide = ArgumentCaptor.forClass(List.class);
3565 verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
3566 assertEquals(1, captorUnhide.getValue().size());
3567 assertEquals("a", captorUnhide.getValue().get(0).sbn.getPackageName());
3568 }
3569
3570 @Test
3571 public void testHideAndUnhideNotificationsOnDistractingPackageBroadcast_multiPkg() {
3572 // Post 2 notifications from 2 packages
3573 NotificationRecord pkgA = new NotificationRecord(mContext,
3574 generateSbn("a", 1000, 9, 0), mTestNotificationChannel);
3575 mService.addNotification(pkgA);
3576 NotificationRecord pkgB = new NotificationRecord(mContext,
3577 generateSbn("b", 1001, 9, 0), mTestNotificationChannel);
3578 mService.addNotification(pkgB);
3579
3580 // on broadcast, hide one of the packages
3581 mService.simulatePackageDistractionBroadcast(
3582 PackageManager.RESTRICTION_HIDE_NOTIFICATIONS, new String[] {"a", "b"});
3583 ArgumentCaptor<List<NotificationRecord>> captorHide = ArgumentCaptor.forClass(List.class);
3584 verify(mListeners, times(2)).notifyHiddenLocked(captorHide.capture());
3585 assertEquals(2, captorHide.getValue().size());
3586 assertEquals("a", captorHide.getValue().get(0).sbn.getPackageName());
3587 assertEquals("b", captorHide.getValue().get(1).sbn.getPackageName());
3588
3589 // on broadcast, unhide the package
3590 mService.simulatePackageDistractionBroadcast(
3591 PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS, new String[] {"a", "b"});
3592 ArgumentCaptor<List<NotificationRecord>> captorUnhide = ArgumentCaptor.forClass(List.class);
3593 verify(mListeners, times(2)).notifyUnhiddenLocked(captorUnhide.capture());
3594 assertEquals(2, captorUnhide.getValue().size());
3595 assertEquals("a", captorUnhide.getValue().get(0).sbn.getPackageName());
3596 assertEquals("b", captorUnhide.getValue().get(1).sbn.getPackageName());
3597 }
3598
3599 @Test
3600 public void testNoNotificationsHiddenOnDistractingPackageBroadcast() {
3601 // post notification from this package
3602 final NotificationRecord notif1 = generateNotificationRecord(
3603 mTestNotificationChannel, 1, null, true);
3604 mService.addNotification(notif1);
3605
3606 // on broadcast, nothing is hidden since no notifications are of package "test_package"
3607 mService.simulatePackageDistractionBroadcast(
3608 PackageManager.RESTRICTION_HIDE_NOTIFICATIONS, new String[] {"test_package"});
3609 ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
3610 verify(mListeners, times(1)).notifyHiddenLocked(captor.capture());
3611 assertEquals(0, captor.getValue().size());
3612 }
3613
3614 @Test
Kristian Monsen05f34792018-04-09 10:27:16 +02003615 public void testCanUseManagedServicesLowRamNoWatchNullPkg() {
3616 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3617 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3618 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3619 .thenReturn(new String[] {"a", "b", "c"});
3620 when(mContext.getResources()).thenReturn(mResources);
3621
3622 assertEquals(false, mService.canUseManagedServices(null));
3623 }
3624
3625 @Test
3626 public void testCanUseManagedServicesLowRamNoWatchValidPkg() {
3627 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3628 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3629 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3630 .thenReturn(new String[] {"a", "b", "c"});
3631 when(mContext.getResources()).thenReturn(mResources);
3632
3633 assertEquals(true, mService.canUseManagedServices("b"));
3634 }
3635
3636 @Test
3637 public void testCanUseManagedServicesLowRamNoWatchNoValidPkg() {
3638 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3639 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3640 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3641 .thenReturn(new String[] {"a", "b", "c"});
3642 when(mContext.getResources()).thenReturn(mResources);
3643
3644 assertEquals(false, mService.canUseManagedServices("d"));
3645 }
3646
3647 @Test
3648 public void testCanUseManagedServicesLowRamWatchNoValidPkg() {
3649 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
3650 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3651 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3652 .thenReturn(new String[] {"a", "b", "c"});
3653 when(mContext.getResources()).thenReturn(mResources);
3654
3655 assertEquals(true, mService.canUseManagedServices("d"));
3656 }
3657
3658 @Test
3659 public void testCanUseManagedServicesNoLowRamNoWatchValidPkg() {
3660 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3661 when(mActivityManager.isLowRamDevice()).thenReturn(false);
3662 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3663 .thenReturn(new String[] {"a", "b", "c"});
3664 when(mContext.getResources()).thenReturn(mResources);
3665
3666 assertEquals(true, mService.canUseManagedServices("d"));
3667 }
3668
3669 @Test
3670 public void testCanUseManagedServicesNoLowRamWatchValidPkg() {
3671 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
3672 when(mActivityManager.isLowRamDevice()).thenReturn(false);
3673 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3674 .thenReturn(new String[] {"a", "b", "c"});
3675 when(mContext.getResources()).thenReturn(mResources);
3676
3677 assertEquals(true, mService.canUseManagedServices("d"));
3678 }
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -04003679
3680 @Test
3681 public void testOnNotificationVisibilityChanged_triggersInterruptionUsageStat() {
3682 final NotificationRecord r = generateNotificationRecord(
3683 mTestNotificationChannel, 1, null, true);
3684 r.setTextChanged(true);
3685 mService.addNotification(r);
3686
3687 mService.mNotificationDelegate.onNotificationVisibilityChanged(new NotificationVisibility[]
3688 {NotificationVisibility.obtain(r.getKey(), 1, 1, true)},
3689 new NotificationVisibility[]{});
3690
3691 verify(mAppUsageStats).reportInterruptiveNotification(anyString(), anyString(), anyInt());
3692 }
3693
3694 @Test
3695 public void testSetNotificationsShownFromListener_triggersInterruptionUsageStat()
3696 throws RemoteException {
3697 final NotificationRecord r = generateNotificationRecord(
3698 mTestNotificationChannel, 1, null, true);
3699 r.setTextChanged(true);
3700 mService.addNotification(r);
3701
3702 mBinderService.setNotificationsShownFromListener(null, new String[] {r.getKey()});
3703
3704 verify(mAppUsageStats).reportInterruptiveNotification(anyString(), anyString(), anyInt());
3705 }
3706
3707 @Test
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04003708 public void testMaybeRecordInterruptionLocked_doesNotRecordTwice()
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -04003709 throws RemoteException {
3710 final NotificationRecord r = generateNotificationRecord(
3711 mTestNotificationChannel, 1, null, true);
3712 r.setInterruptive(true);
3713 mService.addNotification(r);
3714
3715 mService.maybeRecordInterruptionLocked(r);
3716 mService.maybeRecordInterruptionLocked(r);
3717
3718 verify(mAppUsageStats, times(1)).reportInterruptiveNotification(
3719 anyString(), anyString(), anyInt());
3720 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04003721
3722 @Test
Mady Mellorc39b4ae2019-01-09 17:11:37 -08003723 public void testBubble() throws Exception {
3724 mBinderService.setBubblesAllowed(PKG, mUid, false);
3725 assertFalse(mBinderService.areBubblesAllowedForPackage(PKG, mUid));
Julia Reynolds33ab8a02018-12-17 16:19:52 -05003726 }
3727
3728 @Test
Mady Mellor9db685a2019-01-23 13:23:37 -08003729 public void testUserApprovedBubblesForPackage() throws Exception {
3730 assertFalse(mBinderService.hasUserApprovedBubblesForPackage(PKG, mUid));
3731 mBinderService.setBubblesAllowed(PKG, mUid, true);
3732 assertTrue(mBinderService.hasUserApprovedBubblesForPackage(PKG, mUid));
3733 assertTrue(mBinderService.areBubblesAllowedForPackage(PKG, mUid));
3734 }
3735
3736 @Test
3737 public void testUserRejectsBubblesForPackage() throws Exception {
3738 assertFalse(mBinderService.hasUserApprovedBubblesForPackage(PKG, mUid));
3739 mBinderService.setBubblesAllowed(PKG, mUid, false);
3740 assertTrue(mBinderService.hasUserApprovedBubblesForPackage(PKG, mUid));
3741 assertFalse(mBinderService.areBubblesAllowedForPackage(PKG, mUid));
3742 }
3743
3744 @Test
Julia Reynoldsb6634872018-09-25 13:19:53 -04003745 public void testIsCallerInstantApp_primaryUser() throws Exception {
3746 ApplicationInfo info = new ApplicationInfo();
3747 info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
3748 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(info);
Julia Reynolds268647a2018-10-25 16:54:27 -04003749 when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{"any"});
Julia Reynoldsb6634872018-09-25 13:19:53 -04003750
Julia Reynolds268647a2018-10-25 16:54:27 -04003751 assertTrue(mService.isCallerInstantApp(45770, 0));
Julia Reynoldsb6634872018-09-25 13:19:53 -04003752
3753 info.privateFlags = 0;
Julia Reynolds268647a2018-10-25 16:54:27 -04003754 assertFalse(mService.isCallerInstantApp(575370, 0));
Julia Reynoldsb6634872018-09-25 13:19:53 -04003755 }
3756
3757 @Test
3758 public void testIsCallerInstantApp_secondaryUser() throws Exception {
3759 ApplicationInfo info = new ApplicationInfo();
3760 info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
3761 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(10))).thenReturn(info);
3762 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(null);
Julia Reynolds268647a2018-10-25 16:54:27 -04003763 when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{"any"});
Julia Reynoldsb6634872018-09-25 13:19:53 -04003764
Julia Reynolds268647a2018-10-25 16:54:27 -04003765 assertTrue(mService.isCallerInstantApp(68638450, 10));
Julia Reynoldsb6634872018-09-25 13:19:53 -04003766 }
3767
3768 @Test
3769 public void testResolveNotificationUid_sameApp_nonSystemUser() throws Exception {
3770 ApplicationInfo info = new ApplicationInfo();
3771 info.uid = Binder.getCallingUid();
3772 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(10))).thenReturn(info);
3773 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(null);
3774
3775 int actualUid = mService.resolveNotificationUid("caller", "caller", info.uid, 10);
3776
3777 assertEquals(info.uid, actualUid);
3778 }
3779
3780 @Test
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04003781 public void testResolveNotificationUid_sameApp() throws Exception {
3782 ApplicationInfo info = new ApplicationInfo();
3783 info.uid = Binder.getCallingUid();
Julia Reynoldsb6634872018-09-25 13:19:53 -04003784 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(info);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04003785
3786 int actualUid = mService.resolveNotificationUid("caller", "caller", info.uid, 0);
3787
3788 assertEquals(info.uid, actualUid);
3789 }
3790
3791 @Test
Julia Reynoldsecc1b572018-10-01 16:19:24 -04003792 public void testResolveNotificationUid_sameAppDiffPackage() throws Exception {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04003793 ApplicationInfo info = new ApplicationInfo();
3794 info.uid = Binder.getCallingUid();
Julia Reynoldsecc1b572018-10-01 16:19:24 -04003795 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(info);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04003796
Julia Reynoldsecc1b572018-10-01 16:19:24 -04003797 int actualUid = mService.resolveNotificationUid("caller", "callerAlso", info.uid, 0);
3798
3799 assertEquals(info.uid, actualUid);
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -04003800 }
3801
3802 @Test
3803 public void testResolveNotificationUid_sameAppWrongUid() throws Exception {
3804 ApplicationInfo info = new ApplicationInfo();
3805 info.uid = 1356347;
3806 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt())).thenReturn(info);
3807
3808 try {
3809 mService.resolveNotificationUid("caller", "caller", 9, 0);
3810 fail("Incorrect uid didn't throw security exception");
3811 } catch (SecurityException e) {
3812 // yay
3813 }
3814 }
3815
3816 @Test
3817 public void testResolveNotificationUid_delegateAllowed() throws Exception {
3818 int expectedUid = 123;
3819
3820 when(mPackageManagerClient.getPackageUidAsUser("target", 0)).thenReturn(expectedUid);
3821 mService.setPreferencesHelper(mPreferencesHelper);
3822 when(mPreferencesHelper.isDelegateAllowed(anyString(), anyInt(), anyString(), anyInt()))
3823 .thenReturn(true);
3824
3825 assertEquals(expectedUid, mService.resolveNotificationUid("caller", "target", 9, 0));
3826 }
3827
3828 @Test
3829 public void testResolveNotificationUid_androidAllowed() throws Exception {
3830 int expectedUid = 123;
3831
3832 when(mPackageManagerClient.getPackageUidAsUser("target", 0)).thenReturn(expectedUid);
3833 // no delegate
3834
3835 assertEquals(expectedUid, mService.resolveNotificationUid("android", "target", 0, 0));
3836 }
3837
3838 @Test
3839 public void testResolveNotificationUid_delegateNotAllowed() throws Exception {
3840 when(mPackageManagerClient.getPackageUidAsUser("target", 0)).thenReturn(123);
3841 // no delegate
3842
3843 try {
3844 mService.resolveNotificationUid("caller", "target", 9, 0);
3845 fail("Incorrect uid didn't throw security exception");
3846 } catch (SecurityException e) {
3847 // yay
3848 }
3849 }
Julia Reynolds564273f2018-09-13 15:53:11 -04003850
3851 @Test
3852 public void testRemoveForegroundServiceFlagFromNotification_enqueued() {
3853 Notification n = new Notification.Builder(mContext, "").build();
3854 n.flags |= FLAG_FOREGROUND_SERVICE;
3855
3856 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0,
3857 n, new UserHandle(mUid), null, 0);
3858 NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
3859
3860 mService.addEnqueuedNotification(r);
3861
3862 mInternalService.removeForegroundServiceFlagFromNotification(
3863 PKG, r.sbn.getId(), r.sbn.getUserId());
3864
3865 waitForIdle();
3866
3867 verify(mListeners, timeout(200).times(0)).notifyPostedLocked(any(), any());
3868 }
3869
3870 @Test
3871 public void testRemoveForegroundServiceFlagFromNotification_posted() {
3872 Notification n = new Notification.Builder(mContext, "").build();
3873 n.flags |= FLAG_FOREGROUND_SERVICE;
3874
3875 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0,
3876 n, new UserHandle(mUid), null, 0);
3877 NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
3878
3879 mService.addNotification(r);
3880
3881 mInternalService.removeForegroundServiceFlagFromNotification(
3882 PKG, r.sbn.getId(), r.sbn.getUserId());
3883
3884 waitForIdle();
3885
3886 ArgumentCaptor<NotificationRecord> captor =
3887 ArgumentCaptor.forClass(NotificationRecord.class);
3888 verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any());
3889
3890 assertEquals(0, captor.getValue().getNotification().flags);
3891 }
Beverly58b24532018-10-02 09:08:23 -04003892
3893 @Test
3894 public void testAllowForegroundToasts() throws Exception {
3895 final String testPackage = "testPackageName";
3896 assertEquals(0, mService.mToastQueue.size());
3897 mService.isSystemUid = false;
3898
3899 // package is not suspended
3900 when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
3901 .thenReturn(false);
3902
3903 // notifications from this package are blocked by the user
3904 mService.setPreferencesHelper(mPreferencesHelper);
3905 when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);
3906
3907 // this app is in the foreground
3908 when(mActivityManager.getUidImportance(mUid)).thenReturn(IMPORTANCE_FOREGROUND);
3909
3910 // enqueue toast -> toast should still enqueue
3911 ((INotificationManager)mService.mService).enqueueToast(testPackage,
3912 new TestableToastCallback(), 2000, 0);
3913 assertEquals(1, mService.mToastQueue.size());
3914 }
3915
3916 @Test
3917 public void testDisallowToastsFromSuspendedPackages() throws Exception {
3918 final String testPackage = "testPackageName";
3919 assertEquals(0, mService.mToastQueue.size());
3920 mService.isSystemUid = false;
3921
3922 // package is suspended
3923 when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
3924 .thenReturn(true);
3925
3926 // notifications from this package are NOT blocked by the user
3927 mService.setPreferencesHelper(mPreferencesHelper);
3928 when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_LOW);
3929
3930 // enqueue toast -> no toasts enqueued
3931 ((INotificationManager)mService.mService).enqueueToast(testPackage,
3932 new TestableToastCallback(), 2000, 0);
3933 assertEquals(0, mService.mToastQueue.size());
3934 }
3935
3936 @Test
3937 public void testDisallowToastsFromBlockedApps() throws Exception {
3938 final String testPackage = "testPackageName";
3939 assertEquals(0, mService.mToastQueue.size());
3940 mService.isSystemUid = false;
3941
3942 // package is not suspended
3943 when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
3944 .thenReturn(false);
3945
3946 // notifications from this package are blocked by the user
3947 mService.setPreferencesHelper(mPreferencesHelper);
3948 when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);
3949
3950 // this app is NOT in the foreground
3951 when(mActivityManager.getUidImportance(mUid)).thenReturn(IMPORTANCE_GONE);
3952
3953 // enqueue toast -> no toasts enqueued
3954 ((INotificationManager)mService.mService).enqueueToast(testPackage,
3955 new TestableToastCallback(), 2000, 0);
3956 assertEquals(0, mService.mToastQueue.size());
3957 }
3958
3959 @Test
3960 public void testAlwaysAllowSystemToasts() throws Exception {
3961 final String testPackage = "testPackageName";
3962 assertEquals(0, mService.mToastQueue.size());
3963 mService.isSystemUid = true;
3964
3965 // package is suspended
3966 when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
3967 .thenReturn(true);
3968
3969 // notifications from this package ARE blocked by the user
3970 mService.setPreferencesHelper(mPreferencesHelper);
3971 when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);
3972
3973 // this app is NOT in the foreground
3974 when(mActivityManager.getUidImportance(mUid)).thenReturn(IMPORTANCE_GONE);
3975
3976 // enqueue toast -> system toast can still be enqueued
3977 ((INotificationManager)mService.mService).enqueueToast(testPackage,
3978 new TestableToastCallback(), 2000, 0);
3979 assertEquals(1, mService.mToastQueue.size());
3980 }
Tony Mak29996702018-11-26 16:23:34 +00003981
3982 @Test
3983 public void testOnNotificationSmartReplySent() {
3984 final int replyIndex = 2;
3985 final String reply = "Hello";
Milo Sredkov13d88112019-02-01 12:23:24 +00003986 final boolean modifiedBeforeSending = true;
Tony Mak29996702018-11-26 16:23:34 +00003987 final boolean generatedByAssistant = true;
3988
3989 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Milo Sredkov13d88112019-02-01 12:23:24 +00003990 r.setSuggestionsGeneratedByAssistant(generatedByAssistant);
Tony Mak29996702018-11-26 16:23:34 +00003991 mService.addNotification(r);
3992
3993 mService.mNotificationDelegate.onNotificationSmartReplySent(
Milo Sredkov13d88112019-02-01 12:23:24 +00003994 r.getKey(), replyIndex, reply, NOTIFICATION_LOCATION_UNKNOWN,
3995 modifiedBeforeSending);
Tony Mak29996702018-11-26 16:23:34 +00003996 verify(mAssistants).notifyAssistantSuggestedReplySent(
3997 eq(r.sbn), eq(reply), eq(generatedByAssistant));
3998 }
Tony Mak7d4b3a52018-11-27 17:29:36 +00003999
4000 @Test
4001 public void testOnNotificationActionClick() {
4002 final int actionIndex = 2;
4003 final Notification.Action action =
4004 new Notification.Action.Builder(null, "text", null).build();
4005 final boolean generatedByAssistant = false;
4006
4007 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
4008 mService.addNotification(r);
4009
4010 NotificationVisibility notificationVisibility =
4011 NotificationVisibility.obtain(r.getKey(), 1, 2, true);
4012 mService.mNotificationDelegate.onNotificationActionClick(
4013 10, 10, r.getKey(), actionIndex, action, notificationVisibility,
4014 generatedByAssistant);
4015 verify(mAssistants).notifyAssistantActionClicked(
4016 eq(r.sbn), eq(actionIndex), eq(action), eq(generatedByAssistant));
4017 }
Gustav Sennton44dc5882018-12-13 14:38:50 +00004018
4019 @Test
4020 public void testLogSmartSuggestionsVisible_triggerOnExpandAndVisible() {
4021 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
4022 mService.addNotification(r);
4023
Gustav Senntona8e38aa2019-01-22 14:55:39 +00004024 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, true,
4025 NOTIFICATION_LOCATION_UNKNOWN);
Gustav Sennton44dc5882018-12-13 14:38:50 +00004026 NotificationVisibility[] notificationVisibility = new NotificationVisibility[] {
4027 NotificationVisibility.obtain(r.getKey(), 0, 0, true)
4028 };
4029 mService.mNotificationDelegate.onNotificationVisibilityChanged(notificationVisibility,
4030 new NotificationVisibility[0]);
4031
4032 assertEquals(1, mService.countLogSmartSuggestionsVisible);
4033 }
4034
4035 @Test
4036 public void testLogSmartSuggestionsVisible_noTriggerOnExpand() {
4037 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
4038 mService.addNotification(r);
4039
Gustav Senntona8e38aa2019-01-22 14:55:39 +00004040 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, true,
4041 NOTIFICATION_LOCATION_UNKNOWN);
Gustav Sennton44dc5882018-12-13 14:38:50 +00004042
4043 assertEquals(0, mService.countLogSmartSuggestionsVisible);
4044 }
4045
4046 @Test
4047 public void testLogSmartSuggestionsVisible_noTriggerOnVisible() {
4048 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
4049 mService.addNotification(r);
4050
Julia Reynolds95334132018-12-19 11:15:35 -05004051 NotificationVisibility[] notificationVisibility = new NotificationVisibility[]{
Gustav Sennton44dc5882018-12-13 14:38:50 +00004052 NotificationVisibility.obtain(r.getKey(), 0, 0, true)
4053 };
4054 mService.mNotificationDelegate.onNotificationVisibilityChanged(notificationVisibility,
4055 new NotificationVisibility[0]);
4056
4057 assertEquals(0, mService.countLogSmartSuggestionsVisible);
4058 }
Julia Reynolds95334132018-12-19 11:15:35 -05004059
4060 public void testReportSeen_delegated() {
4061 Notification.Builder nb =
4062 new Notification.Builder(mContext, mTestNotificationChannel.getId())
4063 .setContentTitle("foo")
4064 .setSmallIcon(android.R.drawable.sym_def_app_icon);
4065
4066 StatusBarNotification sbn = new StatusBarNotification(PKG, "opPkg", 0, "tag", mUid, 0,
4067 nb.build(), new UserHandle(mUid), null, 0);
4068 NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
4069
4070 mService.reportSeen(r);
4071 verify(mAppUsageStats, never()).reportEvent(anyString(), anyInt(), anyInt());
4072
4073 }
4074
4075 @Test
4076 public void testReportSeen_notDelegated() {
4077 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
4078
4079 mService.reportSeen(r);
4080 verify(mAppUsageStats, times(1)).reportEvent(anyString(), anyInt(), anyInt());
4081 }
Julia Reynolds3207e2f2018-12-20 09:39:53 -05004082
4083 @Test
4084 public void testNotificationStats_notificationError() {
4085 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
4086 mService.addNotification(r);
4087
4088 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
4089 new Notification.Builder(mContext, mTestNotificationChannel.getId()).build(),
4090 new UserHandle(mUid), null, 0);
4091 NotificationRecord update = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
4092 mService.addEnqueuedNotification(update);
4093 assertNull(update.sbn.getNotification().getSmallIcon());
4094
4095 NotificationManagerService.PostNotificationRunnable runnable =
4096 mService.new PostNotificationRunnable(update.getKey());
4097 runnable.run();
4098 waitForIdle();
4099
4100 ArgumentCaptor<NotificationStats> captor = ArgumentCaptor.forClass(NotificationStats.class);
4101 verify(mListeners).notifyRemovedLocked(any(), anyInt(), captor.capture());
4102 assertNotNull(captor.getValue());
4103 }
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -05004104}