blob: 4dcb8cf8b327a96d54a686b4e7b4bd8bc5f43a27 [file] [log] [blame]
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -05001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.notification;
18
Julia Reynoldse5c60452018-04-30 14:41:36 -040019import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -050020import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040021import static android.app.NotificationManager.IMPORTANCE_HIGH;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040022import static android.app.NotificationManager.IMPORTANCE_LOW;
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -050023import static android.app.NotificationManager.IMPORTANCE_MAX;
Julia Reynolds4da79702017-06-01 11:06:10 -040024import static android.app.NotificationManager.IMPORTANCE_NONE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040025import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -050026import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
27import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
28import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
29import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
30import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
31import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
32import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
33import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
34import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
Julia Reynoldse1816412017-10-24 10:39:11 -040035import static android.content.pm.PackageManager.FEATURE_WATCH;
Julia Reynolds4db59552017-06-30 13:34:01 -040036import static android.content.pm.PackageManager.PERMISSION_DENIED;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -050037import static android.os.Build.VERSION_CODES.O_MR1;
38import static android.os.Build.VERSION_CODES.P;
Julia Reynolds70aaea72018-07-13 13:38:34 -040039import static android.service.notification.NotificationListenerService.Ranking
40 .USER_SENTIMENT_NEGATIVE;
41import static android.service.notification.NotificationListenerService.Ranking
42 .USER_SENTIMENT_NEUTRAL;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040043
Geoffrey Pitsch03533712017-01-05 10:30:07 -050044import static junit.framework.Assert.assertEquals;
Julia Reynolds727a7282017-04-13 10:54:01 -040045import static junit.framework.Assert.assertFalse;
Julia Reynolds92febc32017-10-26 11:30:31 -040046import static junit.framework.Assert.assertNotNull;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040047import static junit.framework.Assert.assertNull;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050048import static junit.framework.Assert.assertTrue;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050049import static junit.framework.Assert.fail;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050050
Julia Reynolds5f20e9f2017-01-30 08:54:53 -050051import static org.mockito.Matchers.anyBoolean;
Julia Reynoldsa78cdff2017-04-26 10:19:25 -040052import static org.mockito.Matchers.anyLong;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050053import static org.mockito.Matchers.anyString;
54import static org.mockito.Matchers.eq;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050055import static org.mockito.Mockito.any;
56import static org.mockito.Mockito.anyInt;
Julia Reynoldseb3dca72017-07-11 10:39:58 -040057import static org.mockito.Mockito.doAnswer;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050058import static org.mockito.Mockito.mock;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040059import static org.mockito.Mockito.never;
60import static org.mockito.Mockito.reset;
Julia Reynolds503ed942017-10-04 16:04:56 -040061import static org.mockito.Mockito.spy;
62import static org.mockito.Mockito.timeout;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050063import static org.mockito.Mockito.times;
64import static org.mockito.Mockito.verify;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050065import static org.mockito.Mockito.when;
66
Julia Reynolds68263d12017-06-21 14:21:19 -040067import android.app.ActivityManager;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040068import android.app.IActivityManager;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050069import android.app.INotificationManager;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050070import android.app.Notification;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040071import android.app.Notification.MessagingStyle.Message;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050072import android.app.NotificationChannel;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040073import android.app.NotificationChannelGroup;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050074import android.app.NotificationManager;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -070075import android.app.IUriGrantsManager;
Jason Parks50322ff2018-03-27 10:23:33 -050076import android.app.admin.DevicePolicyManagerInternal;
Julia Reynolds7217dc92018-03-07 12:12:09 -050077import android.app.usage.UsageStatsManagerInternal;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040078import android.companion.ICompanionDeviceManager;
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -050079import android.content.ComponentName;
Jeff Sharkey6a97cc32018-04-17 12:16:20 -060080import android.content.ContentUris;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050081import android.content.Context;
Beverlyd4f96492017-08-02 13:36:11 -040082import android.content.Intent;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050083import android.content.pm.ApplicationInfo;
84import android.content.pm.IPackageManager;
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -050085import android.content.pm.PackageManager;
Geoffrey Pitsch03533712017-01-05 10:30:07 -050086import android.content.pm.ParceledListSlice;
Kristian Monsen05f34792018-04-09 10:27:16 +020087import android.content.res.Resources;
Julia Reynolds73ed76b2017-04-04 17:04:38 -040088import android.graphics.Color;
Julia Reynolds76c096d2017-06-19 08:16:04 -040089import android.media.AudioManager;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040090import android.net.Uri;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -050091import android.os.Binder;
Julia Reynolds8617e4e2017-09-18 16:52:37 -040092import android.os.Build;
Julia Reynolds503ed942017-10-04 16:04:56 -040093import android.os.Bundle;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040094import android.os.IBinder;
Julia Reynoldsf27d6b22017-04-13 15:48:16 -040095import android.os.Process;
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -040096import android.os.RemoteException;
Julia Reynoldsbaff4002016-12-15 11:34:26 -050097import android.os.UserHandle;
Jeff Sharkey6a97cc32018-04-17 12:16:20 -060098import android.provider.MediaStore;
Chris Wren89aa2262017-05-05 18:05:56 -040099import android.provider.Settings.Secure;
Julia Reynolds503ed942017-10-04 16:04:56 -0400100import android.service.notification.Adjustment;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400101import android.service.notification.NotificationListenerService;
Julia Reynolds503ed942017-10-04 16:04:56 -0400102import android.service.notification.NotificationStats;
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500103import android.service.notification.NotifyingApp;
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500104import android.service.notification.StatusBarNotification;
Geoffrey Pitsch8185d382017-05-19 18:41:32 -0400105import android.test.suitebuilder.annotation.SmallTest;
Jason Monk745d0a82017-04-17 11:34:22 -0400106import android.testing.AndroidTestingRunner;
Julia Reynolds92febc32017-10-26 11:30:31 -0400107import android.testing.TestableContext;
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400108import android.testing.TestableLooper;
Jason Monk745d0a82017-04-17 11:34:22 -0400109import android.testing.TestableLooper.RunWithLooper;
Dan Sandler7d67bd42018-05-15 14:06:38 -0400110import android.text.Html;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400111import android.util.ArrayMap;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400112import android.util.AtomicFile;
Brad Stenning8c991ea2018-07-31 13:33:01 -0700113import android.util.Log;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400114
Kristian Monsen05f34792018-04-09 10:27:16 +0200115import com.android.internal.R;
Julia Reynolds503ed942017-10-04 16:04:56 -0400116import com.android.internal.statusbar.NotificationVisibility;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700117import com.android.server.LocalServices;
Jason Monk74f5e362017-12-06 08:56:33 -0500118import com.android.server.UiServiceTestCase;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400119import com.android.server.lights.Light;
120import com.android.server.lights.LightsManager;
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400121import com.android.server.notification.NotificationManagerService.NotificationAssistants;
122import com.android.server.notification.NotificationManagerService.NotificationListeners;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700123import com.android.server.uri.UriGrantsManagerInternal;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400124
125import org.junit.After;
126import org.junit.Before;
127import org.junit.Test;
128import org.junit.runner.RunWith;
Julia Reynolds40f00d72017-12-12 10:47:32 -0500129import org.mockito.ArgumentCaptor;
130import org.mockito.Mock;
131import org.mockito.MockitoAnnotations;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400132import org.mockito.stubbing.Answer;
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500133
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400134import java.io.BufferedInputStream;
135import java.io.ByteArrayInputStream;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400136import java.io.File;
137import java.io.FileInputStream;
138import java.io.FileOutputStream;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400139import java.util.ArrayList;
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500140import java.util.Arrays;
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500141import java.util.HashSet;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400142import java.util.List;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400143import java.util.Map;
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500144import java.util.Set;
Robin Leed107af62018-04-27 13:55:56 +0200145import java.util.function.Consumer;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500146
Geoffrey Pitsch8185d382017-05-19 18:41:32 -0400147@SmallTest
Jason Monk745d0a82017-04-17 11:34:22 -0400148@RunWith(AndroidTestingRunner.class)
149@RunWithLooper
Jason Monk74f5e362017-12-06 08:56:33 -0500150public class NotificationManagerServiceTest extends UiServiceTestCase {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500151 private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400152 private final int mUid = Binder.getCallingUid();
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500153 private TestableNotificationManagerService mService;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500154 private INotificationManager mBinderService;
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400155 private NotificationManagerInternal mInternalService;
Julia Reynoldsda781472017-04-12 09:41:16 -0400156 @Mock
157 private IPackageManager mPackageManager;
158 @Mock
159 private PackageManager mPackageManagerClient;
Julia Reynolds92febc32017-10-26 11:30:31 -0400160 private TestableContext mContext = spy(getContext());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500161 private final String PKG = mContext.getPackageName();
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400162 private TestableLooper mTestableLooper;
Julia Reynoldsda781472017-04-12 09:41:16 -0400163 @Mock
164 private RankingHelper mRankingHelper;
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400165 @Mock private PreferencesHelper mPreferencesHelper;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400166 AtomicFile mPolicyFile;
167 File mFile;
168 @Mock
Geoffrey Pitschd5bcf212017-06-01 15:45:35 -0400169 private NotificationUsageStats mUsageStats;
Julia Reynolds76c096d2017-06-19 08:16:04 -0400170 @Mock
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -0400171 private UsageStatsManagerInternal mAppUsageStats;
172 @Mock
Julia Reynolds76c096d2017-06-19 08:16:04 -0400173 private AudioManager mAudioManager;
Julia Reynolds68263d12017-06-21 14:21:19 -0400174 @Mock
175 ActivityManager mActivityManager;
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400176 NotificationManagerService.WorkerHandler mHandler;
Kristian Monsen05f34792018-04-09 10:27:16 +0200177 @Mock
178 Resources mResources;
Julia Reynolds3ff26d22017-06-19 08:16:04 -0400179
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500180 private NotificationChannel mTestNotificationChannel = new NotificationChannel(
181 TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
Julia Reynoldsda781472017-04-12 09:41:16 -0400182 @Mock
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400183 private NotificationListeners mListeners;
184 @Mock private NotificationAssistants mAssistants;
Julia Reynoldsb852e562017-06-06 16:14:18 -0400185 @Mock private ConditionProviders mConditionProviders;
Julia Reynoldsda781472017-04-12 09:41:16 -0400186 private ManagedServices.ManagedServiceInfo mListener;
187 @Mock private ICompanionDeviceManager mCompanionMgr;
Julia Reynoldsa78cdff2017-04-26 10:19:25 -0400188 @Mock SnoozeHelper mSnoozeHelper;
Julia Reynolds8aebf352017-06-26 11:35:33 -0400189 @Mock GroupHelper mGroupHelper;
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400190 @Mock
191 IBinder mPermOwner;
192 @Mock
193 IActivityManager mAm;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700194 @Mock
195 IUriGrantsManager mUgm;
196 @Mock
197 UriGrantsManagerInternal mUgmInternal;
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500198
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400199 // Use a Testable subclass so we can simulate calls from the system without failing.
200 private static class TestableNotificationManagerService extends NotificationManagerService {
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500201 int countSystemChecks = 0;
Brad Stenning8c991ea2018-07-31 13:33:01 -0700202 boolean isSystemUid = true;
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500203
Amith Yamasani803eab692017-11-09 17:47:04 -0800204 public TestableNotificationManagerService(Context context) {
205 super(context);
206 }
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400207
208 @Override
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400209 protected boolean isCallingUidSystem() {
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500210 countSystemChecks++;
Brad Stenning8c991ea2018-07-31 13:33:01 -0700211 return isSystemUid;
Geoffrey Pitsch27684152017-05-02 11:41:31 -0400212 }
213
214 @Override
215 protected boolean isCallerSystemOrPhone() {
Julia Reynoldsd78263d2018-01-30 10:40:41 -0500216 countSystemChecks++;
Brad Stenning8c991ea2018-07-31 13:33:01 -0700217 return isSystemUid;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400218 }
Julia Reynolds727a7282017-04-13 10:54:01 -0400219
220 @Override
221 protected ICompanionDeviceManager getCompanionManager() {
222 return null;
223 }
Amith Yamasani803eab692017-11-09 17:47:04 -0800224
225 @Override
226 protected void reportSeen(NotificationRecord r) {
227 return;
228 }
Amith Yamasani7ec89412018-02-07 08:48:49 -0800229
230 @Override
231 protected void reportUserInteraction(NotificationRecord r) {
232 return;
233 }
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400234 }
235
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500236 @Before
237 public void setUp() throws Exception {
Julia Reynoldsda781472017-04-12 09:41:16 -0400238 MockitoAnnotations.initMocks(this);
Chris Wren89aa2262017-05-05 18:05:56 -0400239
240 // most tests assume badging is enabled
241 Secure.putIntForUser(getContext().getContentResolver(),
242 Secure.NOTIFICATION_BADGING, 1,
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400243 UserHandle.getUserHandleForUid(mUid).getIdentifier());
Chris Wren89aa2262017-05-05 18:05:56 -0400244
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700245 LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
246 LocalServices.addService(UriGrantsManagerInternal.class, mUgmInternal);
247
Julia Reynolds503ed942017-10-04 16:04:56 -0400248 mService = new TestableNotificationManagerService(mContext);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500249
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400250 // Use this testable looper.
251 mTestableLooper = TestableLooper.get(this);
Julia Reynolds503ed942017-10-04 16:04:56 -0400252 mHandler = mService.new WorkerHandler(mTestableLooper.getLooper());
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500253 // MockPackageManager - default returns ApplicationInfo with matching calling UID
Julia Reynolds92febc32017-10-26 11:30:31 -0400254 mContext.setMockPackageManager(mPackageManagerClient);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500255 final ApplicationInfo applicationInfo = new ApplicationInfo();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400256 applicationInfo.uid = mUid;
Julia Reynolds73ed76b2017-04-04 17:04:38 -0400257 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500258 .thenReturn(applicationInfo);
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500259 when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500260 .thenReturn(applicationInfo);
Julia Reynolds92febc32017-10-26 11:30:31 -0400261 when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid);
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500262 final LightsManager mockLightsManager = mock(LightsManager.class);
263 when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
Julia Reynolds76c096d2017-06-19 08:16:04 -0400264 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
Julia Reynoldse1816412017-10-24 10:39:11 -0400265 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700266 when(mUgmInternal.newUriPermissionOwner(anyString())).thenReturn(mPermOwner);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500267
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400268 // write to a test file; the system file isn't readable from tests
Julia Reynoldsb852e562017-06-06 16:14:18 -0400269 mFile = new File(mContext.getCacheDir(), "test.xml");
270 mFile.createNewFile();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400271 final String preupgradeXml = "<notification-policy></notification-policy>";
272 mPolicyFile = new AtomicFile(mFile);
273 FileOutputStream fos = mPolicyFile.startWrite();
274 fos.write(preupgradeXml.getBytes());
275 mPolicyFile.finishWrite(fos);
276 FileInputStream fStream = new FileInputStream(mFile);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400277
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400278 // Setup managed services
279 mListener = mListeners.new ManagedServiceInfo(
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400280 null, new ComponentName(PKG, "test_class"), mUid, true, null, 0);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400281 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
282 ManagedServices.Config listenerConfig = new ManagedServices.Config();
283 listenerConfig.xmlTag = NotificationListeners.TAG_ENABLED_NOTIFICATION_LISTENERS;
284 when(mListeners.getConfig()).thenReturn(listenerConfig);
285 ManagedServices.Config assistantConfig = new ManagedServices.Config();
286 assistantConfig.xmlTag = NotificationAssistants.TAG_ENABLED_NOTIFICATION_ASSISTANTS;
287 when(mAssistants.getConfig()).thenReturn(assistantConfig);
288 ManagedServices.Config dndConfig = new ManagedServices.Config();
289 dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS;
290 when(mConditionProviders.getConfig()).thenReturn(dndConfig);
291
Julia Reynoldsb852e562017-06-06 16:14:18 -0400292 try {
Julia Reynolds503ed942017-10-04 16:04:56 -0400293 mService.init(mTestableLooper.getLooper(),
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400294 mPackageManager, mPackageManagerClient, mockLightsManager,
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400295 mListeners, mAssistants, mConditionProviders,
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400296 mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -0400297 mGroupHelper, mAm, mAppUsageStats,
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700298 mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400299 } catch (SecurityException e) {
300 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
301 throw e;
302 }
303 }
Julia Reynolds503ed942017-10-04 16:04:56 -0400304 mService.setAudioManager(mAudioManager);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500305
306 // Tests call directly into the Binder.
Julia Reynolds503ed942017-10-04 16:04:56 -0400307 mBinderService = mService.getBinderService();
308 mInternalService = mService.getInternalService();
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500309
310 mBinderService.createNotificationChannels(
311 PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel)));
Julia Reynolds92febc32017-10-26 11:30:31 -0400312 assertNotNull(mBinderService.getNotificationChannel(PKG, TEST_CHANNEL_ID));
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500313 }
314
Julia Reynoldsb852e562017-06-06 16:14:18 -0400315 @After
316 public void tearDown() throws Exception {
317 mFile.delete();
318 }
319
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500320 public void waitForIdle() {
Geoffrey Pitsch415e4542017-04-10 13:12:58 -0400321 mTestableLooper.processAllMessages();
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500322 }
323
Julia Reynolds7bcb57b2018-01-22 10:37:58 -0500324 private StatusBarNotification generateSbn(String pkg, int uid, long postTime, int userId) {
325 Notification.Builder nb = new Notification.Builder(mContext, "a")
326 .setContentTitle("foo")
327 .setSmallIcon(android.R.drawable.sym_def_app_icon);
328 StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, uid, "tag", uid, 0,
329 nb.build(), new UserHandle(userId), null, postTime);
330 return sbn;
331 }
332
Julia Reynoldsa78cdff2017-04-26 10:19:25 -0400333 private NotificationRecord generateNotificationRecord(NotificationChannel channel, int id,
334 String groupKey, boolean isSummary) {
335 Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
336 .setContentTitle("foo")
337 .setSmallIcon(android.R.drawable.sym_def_app_icon)
338 .setGroup(groupKey)
339 .setGroupSummary(isSummary);
340
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400341 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
342 nb.build(), new UserHandle(mUid), null, 0);
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000343 return new NotificationRecord(mContext, sbn, channel);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -0400344 }
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400345
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500346 private NotificationRecord generateNotificationRecord(NotificationChannel channel) {
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500347 return generateNotificationRecord(channel, null);
348 }
349
350 private NotificationRecord generateNotificationRecord(NotificationChannel channel,
351 Notification.TvExtender extender) {
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500352 if (channel == null) {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500353 channel = mTestNotificationChannel;
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500354 }
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500355 Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500356 .setContentTitle("foo")
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500357 .setSmallIcon(android.R.drawable.sym_def_app_icon);
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500358 if (extender != null) {
359 nb.extend(extender);
360 }
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400361 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
362 nb.build(), new UserHandle(mUid), null, 0);
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000363 return new NotificationRecord(mContext, sbn, channel);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500364 }
365
Julia Reynoldseb3dca72017-07-11 10:39:58 -0400366 private Map<String, Answer> getSignalExtractorSideEffects() {
367 Map<String, Answer> answers = new ArrayMap<>();
368
369 answers.put("override group key", invocationOnMock -> {
370 ((NotificationRecord) invocationOnMock.getArguments()[0])
371 .setOverrideGroupKey("bananas");
372 return null;
373 });
374 answers.put("override people", invocationOnMock -> {
375 ((NotificationRecord) invocationOnMock.getArguments()[0])
376 .setPeopleOverride(new ArrayList<>());
377 return null;
378 });
379 answers.put("snooze criteria", invocationOnMock -> {
380 ((NotificationRecord) invocationOnMock.getArguments()[0])
381 .setSnoozeCriteria(new ArrayList<>());
382 return null;
383 });
384 answers.put("notification channel", invocationOnMock -> {
385 ((NotificationRecord) invocationOnMock.getArguments()[0])
386 .updateNotificationChannel(new NotificationChannel("a", "", IMPORTANCE_LOW));
387 return null;
388 });
389 answers.put("badging", invocationOnMock -> {
390 NotificationRecord r = (NotificationRecord) invocationOnMock.getArguments()[0];
391 r.setShowBadge(!r.canShowBadge());
392 return null;
393 });
394 answers.put("package visibility", invocationOnMock -> {
395 ((NotificationRecord) invocationOnMock.getArguments()[0]).setPackageVisibilityOverride(
396 Notification.VISIBILITY_SECRET);
397 return null;
398 });
399
400 return answers;
401 }
402
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500403 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500404 public void testCreateNotificationChannels_SingleChannel() throws Exception {
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500405 final NotificationChannel channel =
406 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400407 mBinderService.createNotificationChannels(PKG,
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500408 new ParceledListSlice(Arrays.asList(channel)));
409 final NotificationChannel createdChannel =
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400410 mBinderService.getNotificationChannel(PKG, "id");
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500411 assertTrue(createdChannel != null);
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500412 }
413
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500414 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500415 public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception {
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500416 try {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400417 mBinderService.createNotificationChannels(PKG,
Kristian Monsen05f34792018-04-09 10:27:16 +0200418 new ParceledListSlice(Arrays.asList((Object[])null)));
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500419 fail("Exception should be thrown immediately.");
420 } catch (NullPointerException e) {
421 // pass
422 }
423 }
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500424
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500425 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500426 public void testCreateNotificationChannels_TwoChannels() throws Exception {
427 final NotificationChannel channel1 =
428 new NotificationChannel("id1", "name", NotificationManager.IMPORTANCE_DEFAULT);
429 final NotificationChannel channel2 =
430 new NotificationChannel("id2", "name", NotificationManager.IMPORTANCE_DEFAULT);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400431 mBinderService.createNotificationChannels(PKG,
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500432 new ParceledListSlice(Arrays.asList(channel1, channel2)));
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400433 assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null);
434 assertTrue(mBinderService.getNotificationChannel(PKG, "id2") != null);
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500435 }
436
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500437 @Test
Geoffrey Pitsch76a3aa02017-07-26 15:07:34 -0400438 public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance()
439 throws Exception {
440 final NotificationChannel channel =
441 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
442 mBinderService.createNotificationChannels(PKG,
443 new ParceledListSlice(Arrays.asList(channel)));
444
445 // Recreating the channel doesn't throw, but ignores importance.
446 final NotificationChannel dupeChannel =
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400447 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
Geoffrey Pitsch76a3aa02017-07-26 15:07:34 -0400448 mBinderService.createNotificationChannels(PKG,
449 new ParceledListSlice(Arrays.asList(dupeChannel)));
450 final NotificationChannel createdChannel =
451 mBinderService.getNotificationChannel(PKG, "id");
452 assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
453 }
454
455 @Test
456 public void testCreateNotificationChannels_SecondCreateAllowedToDowngradeImportance()
457 throws Exception {
458 final NotificationChannel channel =
459 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
460 mBinderService.createNotificationChannels(PKG,
461 new ParceledListSlice(Arrays.asList(channel)));
462
463 // Recreating with a lower importance is allowed to modify the channel.
464 final NotificationChannel dupeChannel =
465 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
466 mBinderService.createNotificationChannels(PKG,
467 new ParceledListSlice(Arrays.asList(dupeChannel)));
468 final NotificationChannel createdChannel =
469 mBinderService.getNotificationChannel(PKG, "id");
470 assertEquals(NotificationManager.IMPORTANCE_LOW, createdChannel.getImportance());
471 }
472
473 @Test
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400474 public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated()
475 throws Exception {
476 final NotificationChannel channel =
477 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
478 mBinderService.createNotificationChannels(PKG,
479 new ParceledListSlice(Arrays.asList(channel)));
480
481 // The user modifies importance directly, can no longer be changed by the app.
482 final NotificationChannel updatedChannel =
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400483 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400484 mBinderService.updateNotificationChannelForPackage(PKG, mUid, updatedChannel);
485
486 // Recreating with a lower importance leaves channel unchanged.
487 final NotificationChannel dupeChannel =
488 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
489 mBinderService.createNotificationChannels(PKG,
490 new ParceledListSlice(Arrays.asList(dupeChannel)));
491 final NotificationChannel createdChannel =
492 mBinderService.getNotificationChannel(PKG, "id");
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400493 assertEquals(IMPORTANCE_HIGH, createdChannel.getImportance());
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400494 }
495
496 @Test
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500497 public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond()
498 throws Exception {
499 final NotificationChannel channel1 =
500 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
501 final NotificationChannel channel2 =
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400502 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400503 mBinderService.createNotificationChannels(PKG,
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500504 new ParceledListSlice(Arrays.asList(channel1, channel2)));
505 final NotificationChannel createdChannel =
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400506 mBinderService.getNotificationChannel(PKG, "id");
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500507 assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
508 }
509
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500510 @Test
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500511 public void testBlockedNotifications_suspended() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500512 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(true);
513
514 NotificationChannel channel = new NotificationChannel("id", "name",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400515 IMPORTANCE_HIGH);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500516 NotificationRecord r = generateNotificationRecord(channel);
Julia Reynolds503ed942017-10-04 16:04:56 -0400517 assertTrue(mService.isBlocked(r, mUsageStats));
Geoffrey Pitschd5bcf212017-06-01 15:45:35 -0400518 verify(mUsageStats, times(1)).registerSuspendedByAdmin(eq(r));
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500519 }
520
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500521 @Test
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500522 public void testBlockedNotifications_blockedChannel() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500523 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
524
525 NotificationChannel channel = new NotificationChannel("id", "name",
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400526 NotificationManager.IMPORTANCE_NONE);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500527 NotificationRecord r = generateNotificationRecord(channel);
Julia Reynolds503ed942017-10-04 16:04:56 -0400528 assertTrue(mService.isBlocked(r, mUsageStats));
Geoffrey Pitschd5bcf212017-06-01 15:45:35 -0400529 verify(mUsageStats, times(1)).registerBlocked(eq(r));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400530
531 mBinderService.createNotificationChannels(
532 PKG, new ParceledListSlice(Arrays.asList(channel)));
533 final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
534 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
535 sbn.getId(), sbn.getNotification(), sbn.getUserId());
536 waitForIdle();
537 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
538 }
539
540 @Test
541 public void testEnqueuedBlockedNotifications_appBlockedChannelForegroundService()
542 throws Exception {
543 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
544
545 NotificationChannel channel = new NotificationChannel("blocked", "name",
546 NotificationManager.IMPORTANCE_NONE);
547 mBinderService.createNotificationChannels(
548 PKG, new ParceledListSlice(Arrays.asList(channel)));
549
550 final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400551 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400552 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
553 sbn.getId(), sbn.getNotification(), sbn.getUserId());
554 waitForIdle();
555 assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
556 assertEquals(IMPORTANCE_LOW,
Julia Reynolds503ed942017-10-04 16:04:56 -0400557 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400558 assertEquals(IMPORTANCE_LOW,
559 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
560 }
561
562 @Test
563 public void testEnqueuedBlockedNotifications_userBlockedChannelForegroundService()
564 throws Exception {
565 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
566
567 NotificationChannel channel =
568 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_HIGH);
569 mBinderService.createNotificationChannels(
570 PKG, new ParceledListSlice(Arrays.asList(channel)));
571
572 NotificationChannel update =
573 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
574 mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
575 waitForIdle();
576 assertEquals(IMPORTANCE_NONE,
577 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
578
Dianne Hackborn025d4a52018-04-30 16:23:26 -0700579 StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400580 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400581 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
582 sbn.getId(), sbn.getNotification(), sbn.getUserId());
583 waitForIdle();
Dianne Hackborn025d4a52018-04-30 16:23:26 -0700584 // The first time a foreground service notification is shown, we allow the channel
585 // to be updated to allow it to be seen.
586 assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
587 assertEquals(IMPORTANCE_LOW,
588 mService.getNotificationRecord(sbn.getKey()).getImportance());
589 assertEquals(IMPORTANCE_LOW,
590 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
591 mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
592 waitForIdle();
593
594 update = new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
595 update.setFgServiceShown(true);
596 mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
597 waitForIdle();
598 assertEquals(IMPORTANCE_NONE,
599 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
600
601 sbn = generateNotificationRecord(channel).sbn;
602 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
603 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
604 sbn.getId(), sbn.getNotification(), sbn.getUserId());
605 waitForIdle();
606 // The second time it is shown, we keep the user's preference.
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400607 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400608 assertNull(mService.getNotificationRecord(sbn.getKey()));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400609 assertEquals(IMPORTANCE_NONE,
610 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500611 }
612
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500613 @Test
Julia Reynolds005c8b92017-08-24 10:35:53 -0400614 public void testBlockedNotifications_blockedChannelGroup() throws Exception {
615 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -0400616 mService.setPreferencesHelper(mPreferencesHelper);
617 when(mPreferencesHelper.isGroupBlocked(anyString(), anyInt(), anyString())).thenReturn(true);
Julia Reynolds005c8b92017-08-24 10:35:53 -0400618
619 NotificationChannel channel = new NotificationChannel("id", "name",
620 NotificationManager.IMPORTANCE_HIGH);
621 channel.setGroup("something");
622 NotificationRecord r = generateNotificationRecord(channel);
Julia Reynolds503ed942017-10-04 16:04:56 -0400623 assertTrue(mService.isBlocked(r, mUsageStats));
Julia Reynolds005c8b92017-08-24 10:35:53 -0400624 verify(mUsageStats, times(1)).registerBlocked(eq(r));
625 }
626
627 @Test
Julia Reynolds4da79702017-06-01 11:06:10 -0400628 public void testEnqueuedBlockedNotifications_blockedApp() throws Exception {
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500629 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
630
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400631 mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
Julia Reynolds4da79702017-06-01 11:06:10 -0400632
633 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
634 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
635 sbn.getId(), sbn.getNotification(), sbn.getUserId());
636 waitForIdle();
637 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500638 }
639
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500640 @Test
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400641 public void testEnqueuedBlockedNotifications_blockedAppForegroundService() throws Exception {
642 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
643
644 mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
645
646 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400647 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400648 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
649 sbn.getId(), sbn.getNotification(), sbn.getUserId());
650 waitForIdle();
651 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400652 assertNull(mService.getNotificationRecord(sbn.getKey()));
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400653 }
654
Brad Stenning8c991ea2018-07-31 13:33:01 -0700655 /**
656 * Confirm the system user on automotive devices can use car categories
657 */
658 @Test
659 public void testEnqueuedRestrictedNotifications_asSystem() throws Exception {
660 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
661 .thenReturn(true);
662 List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
663 Notification.CATEGORY_CAR_WARNING,
664 Notification.CATEGORY_CAR_INFORMATION);
665 int id = 0;
666 for (String category: categories) {
667 final StatusBarNotification sbn =
668 generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
669 sbn.getNotification().category = category;
670 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
671 sbn.getId(), sbn.getNotification(), sbn.getUserId());
672 }
673 waitForIdle();
674 assertEquals(categories.size(), mBinderService.getActiveNotifications(PKG).length);
675 }
676
677
678 /**
679 * Confirm restricted notification categories only apply to automotive.
680 */
681 @Test
682 public void testEnqueuedRestrictedNotifications_notAutomotive() throws Exception {
683 mService.isSystemUid = false;
684 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
685 .thenReturn(false);
686 List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
687 Notification.CATEGORY_CAR_WARNING,
688 Notification.CATEGORY_CAR_INFORMATION);
689 int id = 0;
690 for (String category: categories) {
691 final StatusBarNotification sbn =
692 generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
693 sbn.getNotification().category = category;
694 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
695 sbn.getId(), sbn.getNotification(), sbn.getUserId());
696 }
697 waitForIdle();
698 assertEquals(categories.size(), mBinderService.getActiveNotifications(PKG).length);
699 }
700
701 /**
702 * Confirm if a non-system user tries to use the car categories on a automotive device that
703 * they will get a security exception
704 */
705 @Test
706 public void testEnqueuedRestrictedNotifications_badUser() throws Exception {
707 mService.isSystemUid = false;
708 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
709 .thenReturn(true);
710 List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
711 Notification.CATEGORY_CAR_WARNING,
712 Notification.CATEGORY_CAR_INFORMATION);
713 for (String category: categories) {
714 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
715 sbn.getNotification().category = category;
716 try {
717 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
718 sbn.getId(), sbn.getNotification(), sbn.getUserId());
719 fail("Calls from non system apps should not allow use of restricted categories");
720 } catch (SecurityException e) {
721 // pass
722 }
723 }
724 waitForIdle();
725 assertEquals(0, mBinderService.getActiveNotifications(PKG).length);
726 }
727
Julia Reynolds8617e4e2017-09-18 16:52:37 -0400728 @Test
Julia Reynoldsefcdff42018-08-09 09:42:56 -0400729 public void testBlockedNotifications_blockedByAssistant() throws Exception {
730 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
731
732 NotificationChannel channel = new NotificationChannel("id", "name",
733 NotificationManager.IMPORTANCE_HIGH);
734 NotificationRecord r = generateNotificationRecord(channel);
735 mService.addEnqueuedNotification(r);
736
737 r.setAssistantImportance(IMPORTANCE_NONE);
738
739 NotificationManagerService.PostNotificationRunnable runnable =
740 mService.new PostNotificationRunnable(r.getKey());
741 runnable.run();
742 waitForIdle();
743
744 verify(mUsageStats, never()).registerPostedByApp(any());
745 }
746
747 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500748 public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500749 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400750 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500751 waitForIdle();
Julia Reynolds080361e2017-07-13 11:23:12 -0400752 StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500753 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400754 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500755 }
756
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500757 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500758 public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500759 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400760 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500761 mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500762 waitForIdle();
763 StatusBarNotification[] notifs =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500764 mBinderService.getActiveNotifications(PKG);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500765 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400766 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500767 }
768
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500769 @Test
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500770 public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500771 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400772 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500773 waitForIdle();
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500774 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400775 generateNotificationRecord(null).getNotification(), 0);
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500776 mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500777 waitForIdle();
778 StatusBarNotification[] notifs =
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500779 mBinderService.getActiveNotifications(PKG);
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500780 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400781 assertEquals(0, mService.getNotificationRecordCount());
782 ArgumentCaptor<NotificationStats> captor = ArgumentCaptor.forClass(NotificationStats.class);
783 verify(mListeners, times(1)).notifyRemovedLocked(any(), anyInt(), captor.capture());
784 assertEquals(NotificationStats.DISMISSAL_OTHER, captor.getValue().getDismissalSurface());
Geoffrey Pitschccc0b972017-02-15 10:52:26 -0500785 }
786
787 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500788 public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -0400789 NotificationRecord r = generateNotificationRecord(null);
790 final StatusBarNotification sbn = r.sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500791 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400792 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500793 mBinderService.cancelNotificationsFromListener(null, null);
794 waitForIdle();
795 StatusBarNotification[] notifs =
796 mBinderService.getActiveNotifications(sbn.getPackageName());
797 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400798 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500799 }
800
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500801 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500802 public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
803 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500804 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400805 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500806 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500807 waitForIdle();
808 StatusBarNotification[] notifs =
809 mBinderService.getActiveNotifications(sbn.getPackageName());
810 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400811 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds080361e2017-07-13 11:23:12 -0400812 }
813
814 @Test
815 public void testUserInitiatedClearAll_noLeak() throws Exception {
816 final NotificationRecord n = generateNotificationRecord(
817 mTestNotificationChannel, 1, "group", true);
818
819 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
820 n.sbn.getId(), n.sbn.getNotification(), n.sbn.getUserId());
821 waitForIdle();
822
Julia Reynolds503ed942017-10-04 16:04:56 -0400823 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Julia Reynolds080361e2017-07-13 11:23:12 -0400824 n.getUserId());
825 waitForIdle();
826 StatusBarNotification[] notifs =
827 mBinderService.getActiveNotifications(n.sbn.getPackageName());
828 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());
Julia Reynolds080361e2017-07-13 11:23:12 -0400833 }
834
835 @Test
836 public void testCancelAllNotificationsCancelsChildren() throws Exception {
837 final NotificationRecord parent = generateNotificationRecord(
838 mTestNotificationChannel, 1, "group1", true);
839 final NotificationRecord child = generateNotificationRecord(
840 mTestNotificationChannel, 2, "group1", false);
841
842 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
843 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
844 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
845 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
846 waitForIdle();
847
848 mBinderService.cancelAllNotifications(PKG, parent.sbn.getUserId());
849 waitForIdle();
Julia Reynolds503ed942017-10-04 16:04:56 -0400850 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500851 }
852
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500853 @Test
Julia Reynolds0839c022017-06-15 15:24:01 -0400854 public void testCancelAllNotificationsMultipleEnqueuedDoesNotCrash() throws Exception {
855 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
856 for (int i = 0; i < 10; i++) {
857 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
858 sbn.getId(), sbn.getNotification(), sbn.getUserId());
859 }
860 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
861 waitForIdle();
Julia Reynolds080361e2017-07-13 11:23:12 -0400862
Julia Reynolds503ed942017-10-04 16:04:56 -0400863 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds0839c022017-06-15 15:24:01 -0400864 }
865
866 @Test
867 public void testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash() throws Exception {
868 final NotificationRecord parent = generateNotificationRecord(
869 mTestNotificationChannel, 1, "group1", true);
870 final NotificationRecord parentAsChild = generateNotificationRecord(
871 mTestNotificationChannel, 1, "group1", false);
872 final NotificationRecord child = generateNotificationRecord(
873 mTestNotificationChannel, 2, "group1", false);
874
875 // fully post parent notification
876 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
877 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
878 waitForIdle();
879
880 // enqueue the child several times
881 for (int i = 0; i < 10; i++) {
882 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
883 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
884 }
885 // make the parent a child, which will cancel the child notification
886 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
887 parentAsChild.sbn.getId(), parentAsChild.sbn.getNotification(),
888 parentAsChild.sbn.getUserId());
889 waitForIdle();
Julia Reynolds080361e2017-07-13 11:23:12 -0400890
Julia Reynolds503ed942017-10-04 16:04:56 -0400891 assertEquals(0, mService.getNotificationRecordCount());
Julia Reynolds0839c022017-06-15 15:24:01 -0400892 }
893
894 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500895 public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
896 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400897 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500898 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400899 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500900 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500901 waitForIdle();
902 StatusBarNotification[] notifs =
903 mBinderService.getActiveNotifications(sbn.getPackageName());
904 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400905 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500906 }
907
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500908 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500909 public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
910 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -0400911 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500912 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400913 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500914 mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
915 waitForIdle();
916 StatusBarNotification[] notifs =
917 mBinderService.getActiveNotifications(sbn.getPackageName());
918 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400919 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500920 }
921
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500922 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500923 public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
924 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500925 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400926 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500927 mBinderService.cancelAllNotifications(null, sbn.getUserId());
928 waitForIdle();
929 StatusBarNotification[] notifs =
930 mBinderService.getActiveNotifications(sbn.getPackageName());
931 assertEquals(0, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400932 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500933 }
934
Geoffrey Pitsch16594462017-01-26 14:42:30 -0500935 @Test
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500936 public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
937 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -0500938 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -0400939 sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL);
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500940 // Null pkg is how we signal a user switch.
941 mBinderService.cancelAllNotifications(null, sbn.getUserId());
942 waitForIdle();
943 StatusBarNotification[] notifs =
944 mBinderService.getActiveNotifications(sbn.getPackageName());
945 assertEquals(1, notifs.length);
Julia Reynolds503ed942017-10-04 16:04:56 -0400946 assertEquals(1, mService.getNotificationRecordCount());
Geoffrey Pitsch331a64d2017-01-17 14:00:47 -0500947 }
Julia Reynolds5f20e9f2017-01-30 08:54:53 -0500948
949 @Test
Beverly40239d92017-07-07 10:20:41 -0400950 public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception {
951 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
952 sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR;
953 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
954 sbn.getId(), sbn.getNotification(), sbn.getUserId());
955 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
956 waitForIdle();
957 StatusBarNotification[] notifs =
958 mBinderService.getActiveNotifications(sbn.getPackageName());
959 assertEquals(0, notifs.length);
960 }
961
962 @Test
963 public void testCancelAllNotifications_CancelsNoClearFlag() throws Exception {
964 final NotificationRecord notif = generateNotificationRecord(
965 mTestNotificationChannel, 1, "group", true);
966 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
Julia Reynolds503ed942017-10-04 16:04:56 -0400967 mService.addNotification(notif);
968 mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true,
Beverly40239d92017-07-07 10:20:41 -0400969 notif.getUserId(), 0, null);
970 waitForIdle();
971 StatusBarNotification[] notifs =
972 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
973 assertEquals(0, notifs.length);
974 }
975
976 @Test
977 public void testUserInitiatedCancelAllOnClearAll_NoClearFlag() throws Exception {
978 final NotificationRecord notif = generateNotificationRecord(
979 mTestNotificationChannel, 1, "group", true);
980 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
Julia Reynolds503ed942017-10-04 16:04:56 -0400981 mService.addNotification(notif);
Beverly40239d92017-07-07 10:20:41 -0400982
Julia Reynolds503ed942017-10-04 16:04:56 -0400983 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Beverly40239d92017-07-07 10:20:41 -0400984 notif.getUserId());
985 waitForIdle();
986 StatusBarNotification[] notifs =
987 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
988 assertEquals(1, notifs.length);
989 }
990
991 @Test
992 public void testCancelAllCancelNotificationsFromListener_NoClearFlag() throws Exception {
993 final NotificationRecord parent = generateNotificationRecord(
994 mTestNotificationChannel, 1, "group", true);
995 final NotificationRecord child = generateNotificationRecord(
996 mTestNotificationChannel, 2, "group", false);
997 final NotificationRecord child2 = generateNotificationRecord(
998 mTestNotificationChannel, 3, "group", false);
999 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
1000 final NotificationRecord newGroup = generateNotificationRecord(
1001 mTestNotificationChannel, 4, "group2", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001002 mService.addNotification(parent);
1003 mService.addNotification(child);
1004 mService.addNotification(child2);
1005 mService.addNotification(newGroup);
1006 mService.getBinderService().cancelNotificationsFromListener(null, null);
Beverly40239d92017-07-07 10:20:41 -04001007 waitForIdle();
1008 StatusBarNotification[] notifs =
1009 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1010 assertEquals(1, notifs.length);
1011 }
1012
1013 @Test
1014 public void testUserInitiatedCancelAllWithGroup_NoClearFlag() throws Exception {
1015 final NotificationRecord parent = generateNotificationRecord(
1016 mTestNotificationChannel, 1, "group", true);
1017 final NotificationRecord child = generateNotificationRecord(
1018 mTestNotificationChannel, 2, "group", false);
1019 final NotificationRecord child2 = generateNotificationRecord(
1020 mTestNotificationChannel, 3, "group", false);
1021 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
1022 final NotificationRecord newGroup = generateNotificationRecord(
1023 mTestNotificationChannel, 4, "group2", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001024 mService.addNotification(parent);
1025 mService.addNotification(child);
1026 mService.addNotification(child2);
1027 mService.addNotification(newGroup);
1028 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
Beverly40239d92017-07-07 10:20:41 -04001029 parent.getUserId());
1030 waitForIdle();
1031 StatusBarNotification[] notifs =
1032 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1033 assertEquals(1, notifs.length);
1034 }
1035
1036 @Test
Geoffrey Pitsch415e4542017-04-10 13:12:58 -04001037 public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
1038 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
Julia Reynoldse5c60452018-04-30 14:41:36 -04001039 sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch415e4542017-04-10 13:12:58 -04001040 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -04001041 sbn.getId(), sbn.getNotification(), sbn.getUserId());
Geoffrey Pitsch415e4542017-04-10 13:12:58 -04001042 mInternalService.removeForegroundServiceFlagFromNotification(PKG, sbn.getId(),
1043 sbn.getUserId());
1044 waitForIdle();
1045 StatusBarNotification[] notifs =
1046 mBinderService.getActiveNotifications(sbn.getPackageName());
Julia Reynoldse5c60452018-04-30 14:41:36 -04001047 assertEquals(0, notifs[0].getNotification().flags & FLAG_FOREGROUND_SERVICE);
Geoffrey Pitsch415e4542017-04-10 13:12:58 -04001048 }
1049
1050 @Test
Geoffrey Pitsch27684152017-05-02 11:41:31 -04001051 public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception {
1052 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
1053 sbn.getNotification().flags =
Julia Reynoldse5c60452018-04-30 14:41:36 -04001054 Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
Geoffrey Pitsch27684152017-05-02 11:41:31 -04001055 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
1056 sbn.getId(), sbn.getNotification(), sbn.getUserId());
1057 sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
1058 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
1059 sbn.getId(), sbn.getNotification(), sbn.getUserId());
1060 mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
1061 waitForIdle();
1062 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
Julia Reynolds503ed942017-10-04 16:04:56 -04001063 assertEquals(0, mService.getNotificationRecordCount());
Geoffrey Pitsch27684152017-05-02 11:41:31 -04001064 }
1065
1066 @Test
Julia Reynolds40f00d72017-12-12 10:47:32 -05001067 public void testCancelAllCancelNotificationsFromListener_ForegroundServiceFlag()
1068 throws Exception {
1069 final NotificationRecord parent = generateNotificationRecord(
1070 mTestNotificationChannel, 1, "group", true);
1071 final NotificationRecord child = generateNotificationRecord(
1072 mTestNotificationChannel, 2, "group", false);
1073 final NotificationRecord child2 = generateNotificationRecord(
1074 mTestNotificationChannel, 3, "group", false);
Julia Reynoldse5c60452018-04-30 14:41:36 -04001075 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -05001076 final NotificationRecord newGroup = generateNotificationRecord(
1077 mTestNotificationChannel, 4, "group2", false);
1078 mService.addNotification(parent);
1079 mService.addNotification(child);
1080 mService.addNotification(child2);
1081 mService.addNotification(newGroup);
1082 mService.getBinderService().cancelNotificationsFromListener(null, null);
1083 waitForIdle();
1084 StatusBarNotification[] notifs =
1085 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1086 assertEquals(0, notifs.length);
1087 }
1088
1089 @Test
1090 public void testCancelAllCancelNotificationsFromListener_ForegroundServiceFlagWithParameter()
1091 throws Exception {
1092 final NotificationRecord parent = generateNotificationRecord(
1093 mTestNotificationChannel, 1, "group", true);
1094 final NotificationRecord child = generateNotificationRecord(
1095 mTestNotificationChannel, 2, "group", false);
1096 final NotificationRecord child2 = generateNotificationRecord(
1097 mTestNotificationChannel, 3, "group", false);
Julia Reynoldse5c60452018-04-30 14:41:36 -04001098 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -05001099 final NotificationRecord newGroup = generateNotificationRecord(
1100 mTestNotificationChannel, 4, "group2", false);
1101 mService.addNotification(parent);
1102 mService.addNotification(child);
1103 mService.addNotification(child2);
1104 mService.addNotification(newGroup);
1105 String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
1106 child2.sbn.getKey(), newGroup.sbn.getKey()};
1107 mService.getBinderService().cancelNotificationsFromListener(null, keys);
1108 waitForIdle();
1109 StatusBarNotification[] notifs =
1110 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1111 assertEquals(1, notifs.length);
1112 }
1113
1114 @Test
1115 public void testUserInitiatedCancelAllWithGroup_ForegroundServiceFlag() throws Exception {
1116 final NotificationRecord parent = generateNotificationRecord(
1117 mTestNotificationChannel, 1, "group", true);
1118 final NotificationRecord child = generateNotificationRecord(
1119 mTestNotificationChannel, 2, "group", false);
1120 final NotificationRecord child2 = generateNotificationRecord(
1121 mTestNotificationChannel, 3, "group", false);
Julia Reynoldse5c60452018-04-30 14:41:36 -04001122 child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
Julia Reynolds40f00d72017-12-12 10:47:32 -05001123 final NotificationRecord newGroup = generateNotificationRecord(
1124 mTestNotificationChannel, 4, "group2", false);
1125 mService.addNotification(parent);
1126 mService.addNotification(child);
1127 mService.addNotification(child2);
1128 mService.addNotification(newGroup);
1129 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
1130 parent.getUserId());
1131 waitForIdle();
1132 StatusBarNotification[] notifs =
1133 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1134 assertEquals(0, notifs.length);
1135 }
1136
1137 @Test
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001138 public void testFindGroupNotificationsLocked() throws Exception {
1139 // make sure the same notification can be found in both lists and returned
1140 final NotificationRecord group1 = generateNotificationRecord(
1141 mTestNotificationChannel, 1, "group1", true);
Julia Reynolds503ed942017-10-04 16:04:56 -04001142 mService.addEnqueuedNotification(group1);
1143 mService.addNotification(group1);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001144
1145 // should not be returned
1146 final NotificationRecord group2 = generateNotificationRecord(
1147 mTestNotificationChannel, 2, "group2", true);
1148 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
1149 group2.sbn.getId(), group2.sbn.getNotification(), group2.sbn.getUserId());
1150 waitForIdle();
1151
1152 // should not be returned
1153 final NotificationRecord nonGroup = generateNotificationRecord(
1154 mTestNotificationChannel, 3, null, false);
1155 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
1156 nonGroup.sbn.getId(), nonGroup.sbn.getNotification(), nonGroup.sbn.getUserId());
1157 waitForIdle();
1158
1159 // same group, child, should be returned
1160 final NotificationRecord group1Child = generateNotificationRecord(
1161 mTestNotificationChannel, 4, "group1", false);
1162 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, group1Child.sbn.getId(),
1163 group1Child.sbn.getNotification(), group1Child.sbn.getUserId());
1164 waitForIdle();
1165
1166 List<NotificationRecord> inGroup1 =
Julia Reynolds503ed942017-10-04 16:04:56 -04001167 mService.findGroupNotificationsLocked(PKG, group1.getGroupKey(),
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001168 group1.sbn.getUserId());
1169 assertEquals(3, inGroup1.size());
1170 for (NotificationRecord record : inGroup1) {
1171 assertTrue(record.getGroupKey().equals(group1.getGroupKey()));
1172 assertTrue(record.sbn.getId() == 1 || record.sbn.getId() == 4);
1173 }
1174 }
1175
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001176 @Test
Julia Reynolds40f00d72017-12-12 10:47:32 -05001177 public void testCancelAllNotifications_CancelsNoClearFlagOnGoing() throws Exception {
1178 final NotificationRecord notif = generateNotificationRecord(
1179 mTestNotificationChannel, 1, "group", true);
1180 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
1181 mService.addNotification(notif);
1182 mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0,
1183 Notification.FLAG_ONGOING_EVENT, true, notif.getUserId(), 0, null);
1184 waitForIdle();
1185 StatusBarNotification[] notifs =
1186 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1187 assertEquals(0, notifs.length);
1188 }
1189
1190 @Test
1191 public void testCancelAllCancelNotificationsFromListener_NoClearFlagWithParameter()
1192 throws Exception {
1193 final NotificationRecord parent = generateNotificationRecord(
1194 mTestNotificationChannel, 1, "group", true);
1195 final NotificationRecord child = generateNotificationRecord(
1196 mTestNotificationChannel, 2, "group", false);
1197 final NotificationRecord child2 = generateNotificationRecord(
1198 mTestNotificationChannel, 3, "group", false);
1199 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
1200 final NotificationRecord newGroup = generateNotificationRecord(
1201 mTestNotificationChannel, 4, "group2", false);
1202 mService.addNotification(parent);
1203 mService.addNotification(child);
1204 mService.addNotification(child2);
1205 mService.addNotification(newGroup);
1206 String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
1207 child2.sbn.getKey(), newGroup.sbn.getKey()};
1208 mService.getBinderService().cancelNotificationsFromListener(null, keys);
1209 waitForIdle();
1210 StatusBarNotification[] notifs =
1211 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1212 assertEquals(0, notifs.length);
1213 }
1214
1215 @Test
1216 public void testAppInitiatedCancelAllNotifications_CancelsOnGoingFlag() throws Exception {
1217 final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
1218 sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1219 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
1220 sbn.getId(), sbn.getNotification(), sbn.getUserId());
1221 mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
1222 waitForIdle();
1223 StatusBarNotification[] notifs =
1224 mBinderService.getActiveNotifications(sbn.getPackageName());
1225 assertEquals(0, notifs.length);
1226 }
1227
1228 @Test
1229 public void testCancelAllNotifications_CancelsOnGoingFlag() throws Exception {
1230 final NotificationRecord notif = generateNotificationRecord(
1231 mTestNotificationChannel, 1, "group", true);
1232 notif.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1233 mService.addNotification(notif);
1234 mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true,
1235 notif.getUserId(), 0, null);
1236 waitForIdle();
1237 StatusBarNotification[] notifs =
1238 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1239 assertEquals(0, notifs.length);
1240 }
1241
1242 @Test
1243 public void testUserInitiatedCancelAllOnClearAll_OnGoingFlag() throws Exception {
1244 final NotificationRecord notif = generateNotificationRecord(
1245 mTestNotificationChannel, 1, "group", true);
1246 notif.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1247 mService.addNotification(notif);
1248
1249 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
1250 notif.getUserId());
1251 waitForIdle();
1252 StatusBarNotification[] notifs =
1253 mBinderService.getActiveNotifications(notif.sbn.getPackageName());
1254 assertEquals(1, notifs.length);
1255 }
1256
1257 @Test
1258 public void testCancelAllCancelNotificationsFromListener_OnGoingFlag() throws Exception {
1259 final NotificationRecord parent = generateNotificationRecord(
1260 mTestNotificationChannel, 1, "group", true);
1261 final NotificationRecord child = generateNotificationRecord(
1262 mTestNotificationChannel, 2, "group", false);
1263 final NotificationRecord child2 = generateNotificationRecord(
1264 mTestNotificationChannel, 3, "group", false);
1265 child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1266 final NotificationRecord newGroup = generateNotificationRecord(
1267 mTestNotificationChannel, 4, "group2", false);
1268 mService.addNotification(parent);
1269 mService.addNotification(child);
1270 mService.addNotification(child2);
1271 mService.addNotification(newGroup);
1272 mService.getBinderService().cancelNotificationsFromListener(null, null);
1273 waitForIdle();
1274 StatusBarNotification[] notifs =
1275 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1276 assertEquals(1, notifs.length);
1277 }
1278
1279 @Test
1280 public void testCancelAllCancelNotificationsFromListener_OnGoingFlagWithParameter()
1281 throws Exception {
1282 final NotificationRecord parent = generateNotificationRecord(
1283 mTestNotificationChannel, 1, "group", true);
1284 final NotificationRecord child = generateNotificationRecord(
1285 mTestNotificationChannel, 2, "group", false);
1286 final NotificationRecord child2 = generateNotificationRecord(
1287 mTestNotificationChannel, 3, "group", false);
1288 child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1289 final NotificationRecord newGroup = generateNotificationRecord(
1290 mTestNotificationChannel, 4, "group2", false);
1291 mService.addNotification(parent);
1292 mService.addNotification(child);
1293 mService.addNotification(child2);
1294 mService.addNotification(newGroup);
1295 String[] keys = {parent.sbn.getKey(), child.sbn.getKey(),
1296 child2.sbn.getKey(), newGroup.sbn.getKey()};
1297 mService.getBinderService().cancelNotificationsFromListener(null, keys);
1298 waitForIdle();
1299 StatusBarNotification[] notifs =
1300 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1301 assertEquals(0, notifs.length);
1302 }
1303
1304 @Test
1305 public void testUserInitiatedCancelAllWithGroup_OnGoingFlag() throws Exception {
1306 final NotificationRecord parent = generateNotificationRecord(
1307 mTestNotificationChannel, 1, "group", true);
1308 final NotificationRecord child = generateNotificationRecord(
1309 mTestNotificationChannel, 2, "group", false);
1310 final NotificationRecord child2 = generateNotificationRecord(
1311 mTestNotificationChannel, 3, "group", false);
1312 child2.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
1313 final NotificationRecord newGroup = generateNotificationRecord(
1314 mTestNotificationChannel, 4, "group2", false);
1315 mService.addNotification(parent);
1316 mService.addNotification(child);
1317 mService.addNotification(child2);
1318 mService.addNotification(newGroup);
1319 mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
1320 parent.getUserId());
1321 waitForIdle();
1322 StatusBarNotification[] notifs =
1323 mBinderService.getActiveNotifications(parent.sbn.getPackageName());
1324 assertEquals(1, notifs.length);
1325 }
1326
1327 @Test
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001328 public void testTvExtenderChannelOverride_onTv() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001329 mService.setIsTelevision(true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001330 mService.setPreferencesHelper(mPreferencesHelper);
1331 when(mPreferencesHelper.getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001332 anyString(), anyInt(), eq("foo"), anyBoolean())).thenReturn(
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001333 new NotificationChannel("foo", "foo", IMPORTANCE_HIGH));
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001334
Julia Reynoldsbad42972017-04-25 13:52:49 -04001335 Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001336 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -04001337 generateNotificationRecord(null, tv).getNotification(), 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001338 verify(mPreferencesHelper, times(1)).getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001339 anyString(), anyInt(), eq("foo"), anyBoolean());
1340 }
1341
1342 @Test
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001343 public void testTvExtenderChannelOverride_notOnTv() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001344 mService.setIsTelevision(false);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001345 mService.setPreferencesHelper(mPreferencesHelper);
1346 when(mPreferencesHelper.getNotificationChannel(
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001347 anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001348 mTestNotificationChannel);
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001349
Julia Reynoldsbad42972017-04-25 13:52:49 -04001350 Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001351 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
Julia Reynoldsfea6f7b2017-04-19 13:50:12 -04001352 generateNotificationRecord(null, tv).getNotification(), 0);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001353 verify(mPreferencesHelper, times(1)).getNotificationChannel(
Geoffrey Pitsch1f17e022017-01-03 16:44:20 -05001354 anyString(), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean());
Julia Reynolds5f20e9f2017-01-30 08:54:53 -05001355 }
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001356
1357 @Test
Julia Reynoldsfc9767b2018-01-22 17:45:16 -05001358 public void testUpdateAppNotifyCreatorBlock() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001359 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldsfc9767b2018-01-22 17:45:16 -05001360
1361 mBinderService.setNotificationsEnabledForPackage(PKG, 0, false);
1362 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1363 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1364
1365 assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
1366 captor.getValue().getAction());
1367 assertEquals(PKG, captor.getValue().getPackage());
1368 assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1369 }
1370
1371 @Test
1372 public void testUpdateAppNotifyCreatorUnblock() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001373 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldsfc9767b2018-01-22 17:45:16 -05001374
1375 mBinderService.setNotificationsEnabledForPackage(PKG, 0, true);
1376 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1377 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1378
1379 assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
1380 captor.getValue().getAction());
1381 assertEquals(PKG, captor.getValue().getPackage());
1382 assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
1383 }
1384
1385 @Test
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001386 public void testUpdateChannelNotifyCreatorBlock() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001387 mService.setPreferencesHelper(mPreferencesHelper);
1388 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001389 eq(mTestNotificationChannel.getId()), anyBoolean()))
1390 .thenReturn(mTestNotificationChannel);
1391
1392 NotificationChannel updatedChannel =
1393 new NotificationChannel(mTestNotificationChannel.getId(),
1394 mTestNotificationChannel.getName(), IMPORTANCE_NONE);
1395
1396 mBinderService.updateNotificationChannelForPackage(PKG, 0, updatedChannel);
1397 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1398 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1399
1400 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED,
1401 captor.getValue().getAction());
1402 assertEquals(PKG, captor.getValue().getPackage());
1403 assertEquals(mTestNotificationChannel.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001404 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001405 assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1406 }
1407
1408 @Test
1409 public void testUpdateChannelNotifyCreatorUnblock() throws Exception {
1410 NotificationChannel existingChannel =
1411 new NotificationChannel(mTestNotificationChannel.getId(),
1412 mTestNotificationChannel.getName(), IMPORTANCE_NONE);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001413 mService.setPreferencesHelper(mPreferencesHelper);
1414 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001415 eq(mTestNotificationChannel.getId()), anyBoolean()))
1416 .thenReturn(existingChannel);
1417
1418 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
1419 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1420 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1421
1422 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED,
1423 captor.getValue().getAction());
1424 assertEquals(PKG, captor.getValue().getPackage());
1425 assertEquals(mTestNotificationChannel.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001426 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001427 assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1428 }
1429
1430 @Test
1431 public void testUpdateChannelNoNotifyCreatorOtherChanges() throws Exception {
1432 NotificationChannel existingChannel =
1433 new NotificationChannel(mTestNotificationChannel.getId(),
1434 mTestNotificationChannel.getName(), IMPORTANCE_MAX);
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(existingChannel);
1439
1440 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
1441 verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
1442 }
1443
1444 @Test
1445 public void testUpdateGroupNotifyCreatorBlock() throws Exception {
1446 NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001447 mService.setPreferencesHelper(mPreferencesHelper);
1448 when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001449 .thenReturn(existing);
1450
1451 NotificationChannelGroup updated = new NotificationChannelGroup("id", "name");
1452 updated.setBlocked(true);
1453
1454 mBinderService.updateNotificationChannelGroupForPackage(PKG, 0, updated);
1455 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1456 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1457
1458 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED,
1459 captor.getValue().getAction());
1460 assertEquals(PKG, captor.getValue().getPackage());
1461 assertEquals(existing.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001462 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001463 assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1464 }
1465
1466 @Test
1467 public void testUpdateGroupNotifyCreatorUnblock() throws Exception {
1468 NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
1469 existing.setBlocked(true);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001470 mService.setPreferencesHelper(mPreferencesHelper);
1471 when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001472 .thenReturn(existing);
1473
1474 mBinderService.updateNotificationChannelGroupForPackage(
1475 PKG, 0, new NotificationChannelGroup("id", "name"));
1476 ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
1477 verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
1478
1479 assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED,
1480 captor.getValue().getAction());
1481 assertEquals(PKG, captor.getValue().getPackage());
1482 assertEquals(existing.getId(), captor.getValue().getStringExtra(
Julia Reynolds44ff7c92018-02-05 10:02:30 -05001483 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001484 assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
1485 }
1486
1487 @Test
1488 public void testUpdateGroupNoNotifyCreatorOtherChanges() throws Exception {
1489 NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001490 mService.setPreferencesHelper(mPreferencesHelper);
1491 when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()), eq(PKG), anyInt()))
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001492 .thenReturn(existing);
1493
1494 mBinderService.updateNotificationChannelGroupForPackage(
1495 PKG, 0, new NotificationChannelGroup("id", "new name"));
1496 verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
1497 }
1498
1499 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001500 public void testCreateChannelNotifyListener() throws Exception {
1501 List<String> associations = new ArrayList<>();
1502 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001503 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001504 mService.setPreferencesHelper(mPreferencesHelper);
1505 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001506 eq(mTestNotificationChannel.getId()), anyBoolean()))
1507 .thenReturn(mTestNotificationChannel);
1508 NotificationChannel channel2 = new NotificationChannel("a", "b", IMPORTANCE_LOW);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001509 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001510 eq(channel2.getId()), anyBoolean()))
1511 .thenReturn(channel2);
1512
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001513 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001514 mBinderService.createNotificationChannels(PKG,
1515 new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001516 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001517 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001518 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001519 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001520 eq(Process.myUserHandle()), eq(channel2),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001521 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
1522 }
1523
1524 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001525 public void testCreateChannelGroupNotifyListener() throws Exception {
1526 List<String> associations = new ArrayList<>();
1527 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001528 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001529 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001530 NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
1531 NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
1532
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001533 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001534 mBinderService.createNotificationChannelGroups(PKG,
1535 new ParceledListSlice(Arrays.asList(group1, group2)));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001536 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001537 eq(Process.myUserHandle()), eq(group1),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001538 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001539 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001540 eq(Process.myUserHandle()), eq(group2),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001541 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
1542 }
1543
1544 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001545 public void testUpdateChannelNotifyListener() throws Exception {
1546 List<String> associations = new ArrayList<>();
1547 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001548 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001549 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001550 mTestNotificationChannel.setLightColor(Color.CYAN);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001551 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001552 eq(mTestNotificationChannel.getId()), anyBoolean()))
1553 .thenReturn(mTestNotificationChannel);
1554
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001555 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001556 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001557 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001558 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001559 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1560 }
1561
1562 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001563 public void testDeleteChannelNotifyListener() throws Exception {
1564 List<String> associations = new ArrayList<>();
1565 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001566 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001567 mService.setPreferencesHelper(mPreferencesHelper);
1568 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001569 eq(mTestNotificationChannel.getId()), anyBoolean()))
1570 .thenReturn(mTestNotificationChannel);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001571 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001572 mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001573 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001574 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001575 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
1576 }
1577
1578 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001579 public void testDeleteChannelGroupNotifyListener() throws Exception {
1580 List<String> associations = new ArrayList<>();
1581 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001582 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001583 NotificationChannelGroup ncg = new NotificationChannelGroup("a", "b/c");
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001584 mService.setPreferencesHelper(mPreferencesHelper);
1585 when(mPreferencesHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt()))
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001586 .thenReturn(ncg);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001587 reset(mListeners);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001588 mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001589 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001590 eq(Process.myUserHandle()), eq(ncg),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001591 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
1592 }
1593
1594 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001595 public void testUpdateNotificationChannelFromPrivilegedListener_success() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001596 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001597 List<String> associations = new ArrayList<>();
1598 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001599 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001600 when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -05001601 eq(mTestNotificationChannel.getId()), anyBoolean()))
1602 .thenReturn(mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001603
1604 mBinderService.updateNotificationChannelFromPrivilegedListener(
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001605 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001606
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001607 verify(mPreferencesHelper, times(1)).updateNotificationChannel(
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001608 anyString(), anyInt(), any(), anyBoolean());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001609
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001610 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001611 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001612 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1613 }
1614
1615 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001616 public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001617 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001618 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001619 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001620
1621 try {
1622 mBinderService.updateNotificationChannelFromPrivilegedListener(
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001623 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001624 fail("listeners that don't have a companion device shouldn't be able to call this");
1625 } catch (SecurityException e) {
1626 // pass
1627 }
1628
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001629 verify(mPreferencesHelper, never()).updateNotificationChannel(
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001630 anyString(), anyInt(), any(), anyBoolean());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001631
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001632 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001633 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
1634 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1635 }
1636
1637 @Test
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001638 public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001639 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001640 List<String> associations = new ArrayList<>();
1641 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001642 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001643 mListener = mock(ManagedServices.ManagedServiceInfo.class);
Julia Reynolds4da79702017-06-01 11:06:10 -04001644 mListener.component = new ComponentName(PKG, PKG);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001645 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001646 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001647
1648 try {
1649 mBinderService.updateNotificationChannelFromPrivilegedListener(
1650 null, PKG, UserHandle.ALL, mTestNotificationChannel);
1651 fail("incorrectly allowed a change to a user listener cannot see");
1652 } catch (SecurityException e) {
1653 // pass
1654 }
1655
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001656 verify(mPreferencesHelper, never()).updateNotificationChannel(
Julia Reynolds8617e4e2017-09-18 16:52:37 -04001657 anyString(), anyInt(), any(), anyBoolean());
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001658
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001659 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001660 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001661 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
1662 }
1663
1664 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001665 public void testGetNotificationChannelFromPrivilegedListener_success() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001666 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001667 List<String> associations = new ArrayList<>();
1668 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001669 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001670
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001671 mBinderService.getNotificationChannelsFromPrivilegedListener(
1672 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001673
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001674 verify(mPreferencesHelper, times(1)).getNotificationChannels(
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001675 anyString(), anyInt(), anyBoolean());
1676 }
1677
1678 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001679 public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001680 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001681 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001682 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001683
1684 try {
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001685 mBinderService.getNotificationChannelsFromPrivilegedListener(
1686 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001687 fail("listeners that don't have a companion device shouldn't be able to call this");
1688 } catch (SecurityException e) {
1689 // pass
1690 }
1691
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001692 verify(mPreferencesHelper, never()).getNotificationChannels(
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001693 anyString(), anyInt(), anyBoolean());
1694 }
1695
1696 @Test
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001697 public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001698 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001699 List<String> associations = new ArrayList<>();
1700 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001701 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001702 mListener = mock(ManagedServices.ManagedServiceInfo.class);
1703 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001704 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001705
1706 try {
1707 mBinderService.getNotificationChannelsFromPrivilegedListener(
1708 null, PKG, Process.myUserHandle());
1709 fail("listener getting channels from a user they cannot see");
1710 } catch (SecurityException e) {
1711 // pass
1712 }
1713
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001714 verify(mPreferencesHelper, never()).getNotificationChannels(
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001715 anyString(), anyInt(), anyBoolean());
1716 }
1717
1718 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001719 public void testGetNotificationChannelGroupsFromPrivilegedListener_success() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001720 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001721 List<String> associations = new ArrayList<>();
1722 associations.add("a");
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001723 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001724
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001725 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1726 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001727
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001728 verify(mPreferencesHelper, times(1)).getNotificationChannelGroups(anyString(), anyInt());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001729 }
1730
1731 @Test
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001732 public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001733 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001734 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001735 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001736
1737 try {
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001738 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1739 null, PKG, Process.myUserHandle());
1740 fail("listeners that don't have a companion device shouldn't be able to call this");
1741 } catch (SecurityException e) {
1742 // pass
1743 }
1744
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001745 verify(mPreferencesHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001746 }
1747
1748 @Test
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001749 public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001750 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001751 List<String> associations = new ArrayList<>();
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04001752 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001753 mListener = mock(ManagedServices.ManagedServiceInfo.class);
1754 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001755 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
Julia Reynoldsf27d6b22017-04-13 15:48:16 -04001756
1757 try {
1758 mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
1759 null, PKG, Process.myUserHandle());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001760 fail("listeners that don't have a companion device shouldn't be able to call this");
1761 } catch (SecurityException e) {
1762 // pass
1763 }
1764
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04001765 verify(mPreferencesHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
Julia Reynolds73ed76b2017-04-04 17:04:38 -04001766 }
Julia Reynoldsda781472017-04-12 09:41:16 -04001767
1768 @Test
Julia Reynoldsda781472017-04-12 09:41:16 -04001769 public void testHasCompanionDevice_failure() throws Exception {
1770 when(mCompanionMgr.getAssociations(anyString(), anyInt())).thenThrow(
1771 new IllegalArgumentException());
Julia Reynolds503ed942017-10-04 16:04:56 -04001772 mService.hasCompanionDevice(mListener);
Julia Reynoldsda781472017-04-12 09:41:16 -04001773 }
Julia Reynolds727a7282017-04-13 10:54:01 -04001774
1775 @Test
Julia Reynolds727a7282017-04-13 10:54:01 -04001776 public void testHasCompanionDevice_noService() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04001777 mService = new TestableNotificationManagerService(mContext);
Julia Reynolds727a7282017-04-13 10:54:01 -04001778
Julia Reynolds503ed942017-10-04 16:04:56 -04001779 assertFalse(mService.hasCompanionDevice(mListener));
Julia Reynolds727a7282017-04-13 10:54:01 -04001780 }
1781
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001782 @Test
1783 public void testSnoozeRunnable_snoozeNonGrouped() throws Exception {
1784 final NotificationRecord nonGrouped = generateNotificationRecord(
1785 mTestNotificationChannel, 1, null, false);
1786 final NotificationRecord grouped = generateNotificationRecord(
1787 mTestNotificationChannel, 2, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001788 mService.addNotification(grouped);
1789 mService.addNotification(nonGrouped);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001790
1791 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001792 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001793 nonGrouped.getKey(), 100, null);
1794 snoozeNotificationRunnable.run();
1795
1796 // only snooze the one notification
1797 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
Julia Reynolds503ed942017-10-04 16:04:56 -04001798 assertTrue(nonGrouped.getStats().hasSnoozed());
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001799 }
1800
1801 @Test
1802 public void testSnoozeRunnable_snoozeSummary_withChildren() throws Exception {
1803 final NotificationRecord parent = generateNotificationRecord(
1804 mTestNotificationChannel, 1, "group", true);
1805 final NotificationRecord child = generateNotificationRecord(
1806 mTestNotificationChannel, 2, "group", false);
1807 final NotificationRecord child2 = generateNotificationRecord(
1808 mTestNotificationChannel, 3, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001809 mService.addNotification(parent);
1810 mService.addNotification(child);
1811 mService.addNotification(child2);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001812
1813 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001814 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001815 parent.getKey(), 100, null);
1816 snoozeNotificationRunnable.run();
1817
1818 // snooze parent and children
1819 verify(mSnoozeHelper, times(3)).snooze(any(NotificationRecord.class), anyLong());
1820 }
1821
1822 @Test
1823 public void testSnoozeRunnable_snoozeGroupChild_fellowChildren() throws Exception {
1824 final NotificationRecord parent = generateNotificationRecord(
1825 mTestNotificationChannel, 1, "group", true);
1826 final NotificationRecord child = generateNotificationRecord(
1827 mTestNotificationChannel, 2, "group", false);
1828 final NotificationRecord child2 = generateNotificationRecord(
1829 mTestNotificationChannel, 3, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001830 mService.addNotification(parent);
1831 mService.addNotification(child);
1832 mService.addNotification(child2);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001833
1834 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001835 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001836 child2.getKey(), 100, null);
1837 snoozeNotificationRunnable.run();
1838
1839 // only snooze the one child
1840 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
1841 }
1842
1843 @Test
1844 public void testSnoozeRunnable_snoozeGroupChild_onlyChildOfSummary() throws Exception {
1845 final NotificationRecord parent = generateNotificationRecord(
1846 mTestNotificationChannel, 1, "group", true);
1847 assertTrue(parent.sbn.getNotification().isGroupSummary());
1848 final NotificationRecord child = generateNotificationRecord(
1849 mTestNotificationChannel, 2, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001850 mService.addNotification(parent);
1851 mService.addNotification(child);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001852
1853 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001854 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001855 child.getKey(), 100, null);
1856 snoozeNotificationRunnable.run();
1857
1858 // snooze child and summary
1859 verify(mSnoozeHelper, times(2)).snooze(any(NotificationRecord.class), anyLong());
1860 }
1861
1862 @Test
1863 public void testSnoozeRunnable_snoozeGroupChild_noOthersInGroup() throws Exception {
1864 final NotificationRecord child = generateNotificationRecord(
1865 mTestNotificationChannel, 2, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04001866 mService.addNotification(child);
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001867
1868 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04001869 mService.new SnoozeNotificationRunnable(
Julia Reynoldsa78cdff2017-04-26 10:19:25 -04001870 child.getKey(), 100, null);
1871 snoozeNotificationRunnable.run();
1872
1873 // snooze child only
1874 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
1875 }
1876
1877 @Test
1878 public void testPostGroupChild_unsnoozeParent() throws Exception {
1879 final NotificationRecord child = generateNotificationRecord(
1880 mTestNotificationChannel, 2, "group", false);
1881
1882 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
1883 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
1884 waitForIdle();
1885
1886 verify(mSnoozeHelper, times(1)).repostGroupSummary(
1887 anyString(), anyInt(), eq(child.getGroupKey()));
1888 }
1889
1890 @Test
1891 public void testPostNonGroup_noUnsnoozing() throws Exception {
1892 final NotificationRecord record = generateNotificationRecord(
1893 mTestNotificationChannel, 2, null, false);
1894
1895 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
1896 record.sbn.getId(), record.sbn.getNotification(), record.sbn.getUserId());
1897 waitForIdle();
1898
1899 verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
1900 }
1901
1902 @Test
1903 public void testPostGroupSummary_noUnsnoozing() throws Exception {
1904 final NotificationRecord parent = generateNotificationRecord(
1905 mTestNotificationChannel, 2, "group", true);
1906
1907 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
1908 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
1909 waitForIdle();
1910
1911 verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
1912 }
Julia Reynoldsb852e562017-06-06 16:14:18 -04001913
1914 @Test
Julia Reynolds92febc32017-10-26 11:30:31 -04001915 public void testSetListenerAccessForUser() throws Exception {
1916 UserHandle user = UserHandle.of(10);
1917 ComponentName c = ComponentName.unflattenFromString("package/Component");
1918 try {
1919 mBinderService.setNotificationListenerAccessGrantedForUser(
1920 c, user.getIdentifier(), true);
1921 } catch (SecurityException e) {
1922 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1923 throw e;
1924 }
1925 }
1926
1927 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
1928 verify(mListeners, times(1)).setPackageOrComponentEnabled(
1929 c.flattenToString(), user.getIdentifier(), true, true);
1930 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1931 c.flattenToString(), user.getIdentifier(), false, true);
1932 verify(mAssistants, never()).setPackageOrComponentEnabled(
1933 any(), anyInt(), anyBoolean(), anyBoolean());
1934 }
1935
1936 @Test
1937 public void testSetAssistantAccessForUser() throws Exception {
1938 UserHandle user = UserHandle.of(10);
1939 ComponentName c = ComponentName.unflattenFromString("package/Component");
1940 try {
1941 mBinderService.setNotificationAssistantAccessGrantedForUser(
1942 c, user.getIdentifier(), true);
1943 } catch (SecurityException e) {
1944 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1945 throw e;
1946 }
1947 }
1948
1949 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
1950 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
1951 c.flattenToString(), user.getIdentifier(), true, true);
1952 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1953 c.flattenToString(), user.getIdentifier(), false, true);
1954 verify(mListeners, never()).setPackageOrComponentEnabled(
1955 any(), anyInt(), anyBoolean(), anyBoolean());
1956 }
1957
1958 @Test
1959 public void testSetDndAccessForUser() throws Exception {
1960 UserHandle user = UserHandle.of(10);
1961 ComponentName c = ComponentName.unflattenFromString("package/Component");
1962 try {
1963 mBinderService.setNotificationPolicyAccessGrantedForUser(
1964 c.getPackageName(), user.getIdentifier(), true);
1965 } catch (SecurityException e) {
1966 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1967 throw e;
1968 }
1969 }
1970
1971 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
1972 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1973 c.getPackageName(), user.getIdentifier(), true, true);
1974 verify(mAssistants, never()).setPackageOrComponentEnabled(
1975 any(), anyInt(), anyBoolean(), anyBoolean());
1976 verify(mListeners, never()).setPackageOrComponentEnabled(
1977 any(), anyInt(), anyBoolean(), anyBoolean());
1978 }
1979
1980 @Test
Julia Reynoldsb852e562017-06-06 16:14:18 -04001981 public void testSetListenerAccess() throws Exception {
1982 ComponentName c = ComponentName.unflattenFromString("package/Component");
1983 try {
1984 mBinderService.setNotificationListenerAccessGranted(c, true);
1985 } catch (SecurityException e) {
1986 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
1987 throw e;
1988 }
1989 }
1990
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001991 verify(mListeners, times(1)).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001992 c.flattenToString(), 0, true, true);
1993 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
1994 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001995 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04001996 any(), anyInt(), anyBoolean(), anyBoolean());
1997 }
1998
1999 @Test
2000 public void testSetAssistantAccess() throws Exception {
2001 ComponentName c = ComponentName.unflattenFromString("package/Component");
2002 try {
2003 mBinderService.setNotificationAssistantAccessGranted(c, true);
2004 } catch (SecurityException e) {
2005 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2006 throw e;
2007 }
2008 }
2009
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002010 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04002011 c.flattenToString(), 0, true, true);
2012 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2013 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002014 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04002015 any(), anyInt(), anyBoolean(), anyBoolean());
2016 }
2017
2018 @Test
2019 public void testSetDndAccess() throws Exception {
2020 ComponentName c = ComponentName.unflattenFromString("package/Component");
2021 try {
2022 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
2023 } catch (SecurityException e) {
2024 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2025 throw e;
2026 }
2027 }
2028
2029 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2030 c.getPackageName(), 0, true, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002031 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04002032 any(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002033 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldsb852e562017-06-06 16:14:18 -04002034 any(), anyInt(), anyBoolean(), anyBoolean());
2035 }
Julia Reynolds68263d12017-06-21 14:21:19 -04002036
2037 @Test
2038 public void testSetListenerAccess_doesNothingOnLowRam() throws Exception {
2039 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2040 ComponentName c = ComponentName.unflattenFromString("package/Component");
2041 mBinderService.setNotificationListenerAccessGranted(c, true);
2042
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002043 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002044 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04002045 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002046 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002047 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04002048 any(), anyInt(), anyBoolean(), anyBoolean());
2049 }
2050
2051 @Test
2052 public void testSetAssistantAccess_doesNothingOnLowRam() throws Exception {
2053 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2054 ComponentName c = ComponentName.unflattenFromString("package/Component");
2055 mBinderService.setNotificationAssistantAccessGranted(c, true);
2056
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002057 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002058 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04002059 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002060 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002061 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04002062 any(), anyInt(), anyBoolean(), anyBoolean());
2063 }
2064
2065 @Test
2066 public void testSetDndAccess_doesNothingOnLowRam() throws Exception {
2067 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2068 ComponentName c = ComponentName.unflattenFromString("package/Component");
2069 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
2070
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002071 verify(mListeners, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002072 anyString(), anyInt(), anyBoolean(), anyBoolean());
Julia Reynolds68263d12017-06-21 14:21:19 -04002073 verify(mConditionProviders, never()).setPackageOrComponentEnabled(
Julia Reynoldse1816412017-10-24 10:39:11 -04002074 anyString(), anyInt(), anyBoolean(), anyBoolean());
2075 verify(mAssistants, never()).setPackageOrComponentEnabled(
2076 any(), anyInt(), anyBoolean(), anyBoolean());
2077 }
2078
2079 @Test
2080 public void testSetListenerAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
2081 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
2082 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2083 ComponentName c = ComponentName.unflattenFromString("package/Component");
2084 try {
2085 mBinderService.setNotificationListenerAccessGranted(c, true);
2086 } catch (SecurityException e) {
2087 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2088 throw e;
2089 }
2090 }
2091
2092 verify(mListeners, times(1)).setPackageOrComponentEnabled(
2093 c.flattenToString(), 0, true, true);
2094 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04002095 c.flattenToString(), 0, false, true);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002096 verify(mAssistants, never()).setPackageOrComponentEnabled(
Julia Reynolds68263d12017-06-21 14:21:19 -04002097 any(), anyInt(), anyBoolean(), anyBoolean());
2098 }
Julia Reynolds8aebf352017-06-26 11:35:33 -04002099
2100 @Test
Julia Reynoldse1816412017-10-24 10:39:11 -04002101 public void testSetAssistantAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
2102 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
2103 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2104 ComponentName c = ComponentName.unflattenFromString("package/Component");
2105 try {
2106 mBinderService.setNotificationAssistantAccessGranted(c, true);
2107 } catch (SecurityException e) {
2108 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2109 throw e;
2110 }
2111 }
2112
2113 verify(mListeners, never()).setPackageOrComponentEnabled(
2114 anyString(), anyInt(), anyBoolean(), anyBoolean());
2115 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2116 c.flattenToString(), 0, false, true);
2117 verify(mAssistants, times(1)).setPackageOrComponentEnabled(
2118 c.flattenToString(), 0, true, true);
2119 }
2120
2121 @Test
2122 public void testSetDndAccess_doesNothingOnLowRam_exceptWatch() throws Exception {
2123 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
2124 when(mActivityManager.isLowRamDevice()).thenReturn(true);
2125 ComponentName c = ComponentName.unflattenFromString("package/Component");
2126 try {
2127 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
2128 } catch (SecurityException e) {
2129 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
2130 throw e;
2131 }
2132 }
2133
2134 verify(mListeners, never()).setPackageOrComponentEnabled(
2135 anyString(), anyInt(), anyBoolean(), anyBoolean());
2136 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
2137 c.getPackageName(), 0, true, true);
2138 verify(mAssistants, never()).setPackageOrComponentEnabled(
2139 any(), anyInt(), anyBoolean(), anyBoolean());
2140 }
2141
2142 @Test
Julia Reynolds8aebf352017-06-26 11:35:33 -04002143 public void testOnlyAutogroupIfGroupChanged_noPriorNoti_autogroups() throws Exception {
2144 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002145 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002146 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002147 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002148 runnable.run();
2149 waitForIdle();
2150
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002151 verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002152 }
2153
2154 @Test
2155 public void testOnlyAutogroupIfGroupChanged_groupChanged_autogroups()
2156 throws Exception {
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002157 NotificationRecord r =
2158 generateNotificationRecord(mTestNotificationChannel, 0, "group", false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002159 mService.addNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002160
2161 r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002162 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002163 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002164 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002165 runnable.run();
2166 waitForIdle();
2167
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002168 verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002169 }
2170
2171 @Test
2172 public void testOnlyAutogroupIfGroupChanged_noGroupChanged_autogroups()
2173 throws Exception {
Julia Reynolds4db59552017-06-30 13:34:01 -04002174 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group",
2175 false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002176 mService.addNotification(r);
2177 mService.addEnqueuedNotification(r);
Julia Reynolds8aebf352017-06-26 11:35:33 -04002178
2179 NotificationManagerService.PostNotificationRunnable runnable =
Julia Reynolds503ed942017-10-04 16:04:56 -04002180 mService.new PostNotificationRunnable(r.getKey());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002181 runnable.run();
2182 waitForIdle();
2183
Julia Reynoldsa13b3e22017-08-10 16:58:54 -04002184 verify(mGroupHelper, never()).onNotificationPosted(any(), anyBoolean());
Julia Reynolds8aebf352017-06-26 11:35:33 -04002185 }
Beverly40239d92017-07-07 10:20:41 -04002186
Julia Reynolds4db59552017-06-30 13:34:01 -04002187 @Test
2188 public void testNoFakeColorizedPermission() throws Exception {
2189 when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED);
2190 Notification.Builder nb = new Notification.Builder(mContext,
2191 mTestNotificationChannel.getId())
2192 .setContentTitle("foo")
2193 .setColorized(true)
2194 .setFlag(Notification.FLAG_CAN_COLORIZE, true)
2195 .setSmallIcon(android.R.drawable.sym_def_app_icon);
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002196 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
2197 nb.build(), new UserHandle(mUid), null, 0);
Julia Reynolds4db59552017-06-30 13:34:01 -04002198 NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
2199
2200 mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
2201 nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
2202 waitForIdle();
2203
Julia Reynolds503ed942017-10-04 16:04:56 -04002204 NotificationRecord posted = mService.findNotificationLocked(
Julia Reynolds4db59552017-06-30 13:34:01 -04002205 PKG, null, nr.sbn.getId(), nr.sbn.getUserId());
2206
2207 assertFalse(posted.getNotification().isColorized());
2208 }
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002209
2210 @Test
2211 public void testGetNotificationCountLocked() throws Exception {
2212 for (int i = 0; i < 20; i++) {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002213 NotificationRecord r =
2214 generateNotificationRecord(mTestNotificationChannel, i, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002215 mService.addEnqueuedNotification(r);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002216 }
2217 for (int i = 0; i < 20; i++) {
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002218 NotificationRecord r =
2219 generateNotificationRecord(mTestNotificationChannel, i, null, false);
Julia Reynolds503ed942017-10-04 16:04:56 -04002220 mService.addNotification(r);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002221 }
2222
2223 // another package
2224 Notification n =
2225 new Notification.Builder(mContext, mTestNotificationChannel.getId())
2226 .setSmallIcon(android.R.drawable.sym_def_app_icon)
2227 .build();
2228
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002229 StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "tag", mUid, 0,
2230 n, new UserHandle(mUid), null, 0);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002231 NotificationRecord otherPackage =
2232 new NotificationRecord(mContext, sbn, mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002233 mService.addEnqueuedNotification(otherPackage);
2234 mService.addNotification(otherPackage);
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002235
2236 // Same notifications are enqueued as posted, everything counts b/c id and tag don't match
Geoffrey Pitsch07532c32017-07-18 11:44:06 -04002237 int userId = new UserHandle(mUid).getIdentifier();
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002238 assertEquals(40,
Julia Reynolds503ed942017-10-04 16:04:56 -04002239 mService.getNotificationCountLocked(PKG, userId, 0, null));
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002240 assertEquals(40,
Julia Reynolds503ed942017-10-04 16:04:56 -04002241 mService.getNotificationCountLocked(PKG, userId, 0, "tag2"));
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002242 assertEquals(2,
Julia Reynolds503ed942017-10-04 16:04:56 -04002243 mService.getNotificationCountLocked("a", userId, 0, "banana"));
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002244
2245 // exclude a known notification - it's excluded from only the posted list, not enqueued
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002246 assertEquals(39,
Julia Reynolds503ed942017-10-04 16:04:56 -04002247 mService.getNotificationCountLocked(PKG, userId, 0, "tag"));
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002248 }
2249
2250 @Test
Julia Reynolds51710712017-07-19 13:48:07 -04002251 public void testAddAutogroup_requestsSort() throws Exception {
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002252 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002253 mService.setRankingHandler(rh);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002254
2255 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002256 mService.addNotification(r);
2257 mService.addAutogroupKeyLocked(r.getKey());
Julia Reynolds51710712017-07-19 13:48:07 -04002258
2259 verify(rh, times(1)).requestSort();
2260 }
2261
2262 @Test
2263 public void testRemoveAutogroup_requestsSort() throws Exception {
2264 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002265 mService.setRankingHandler(rh);
Julia Reynolds51710712017-07-19 13:48:07 -04002266
2267 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2268 r.setOverrideGroupKey("TEST");
Julia Reynolds503ed942017-10-04 16:04:56 -04002269 mService.addNotification(r);
2270 mService.removeAutogroupKeyLocked(r.getKey());
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002271
Julia Reynolds51710712017-07-19 13:48:07 -04002272 verify(rh, times(1)).requestSort();
2273 }
2274
2275 @Test
2276 public void testReaddAutogroup_noSort() throws Exception {
2277 RankingHandler rh = mock(RankingHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002278 mService.setRankingHandler(rh);
Julia Reynolds51710712017-07-19 13:48:07 -04002279
2280 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2281 r.setOverrideGroupKey("TEST");
Julia Reynolds503ed942017-10-04 16:04:56 -04002282 mService.addNotification(r);
2283 mService.addAutogroupKeyLocked(r.getKey());
Julia Reynolds51710712017-07-19 13:48:07 -04002284
2285 verify(rh, never()).requestSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002286 }
2287
2288 @Test
2289 public void testHandleRankingSort_sendsUpdateOnSignalExtractorChange() throws Exception {
Aaron Heuckrothe5bec152018-07-09 16:26:09 -04002290 mService.setPreferencesHelper(mPreferencesHelper);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002291 NotificationManagerService.WorkerHandler handler = mock(
2292 NotificationManagerService.WorkerHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002293 mService.setHandler(handler);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002294
2295 Map<String, Answer> answers = getSignalExtractorSideEffects();
2296 for (String message : answers.keySet()) {
Julia Reynolds503ed942017-10-04 16:04:56 -04002297 mService.clearNotifications();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002298 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002299 mService.addNotification(r);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002300
2301 doAnswer(answers.get(message)).when(mRankingHelper).extractSignals(r);
2302
Julia Reynolds503ed942017-10-04 16:04:56 -04002303 mService.handleRankingSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002304 }
2305 verify(handler, times(answers.size())).scheduleSendRankingUpdate();
2306 }
2307
2308 @Test
2309 public void testHandleRankingSort_noUpdateWhenNoSignalChange() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04002310 mService.setRankingHelper(mRankingHelper);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002311 NotificationManagerService.WorkerHandler handler = mock(
2312 NotificationManagerService.WorkerHandler.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002313 mService.setHandler(handler);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002314
2315 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002316 mService.addNotification(r);
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002317
Julia Reynolds503ed942017-10-04 16:04:56 -04002318 mService.handleRankingSort();
Julia Reynoldseb3dca72017-07-11 10:39:58 -04002319 verify(handler, never()).scheduleSendRankingUpdate();
Julia Reynolds6ad0aec2017-07-05 08:47:03 -04002320 }
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002321
2322 @Test
2323 public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception {
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002324 final String upgradeXml = "<notification-policy version=\"1\">"
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002325 + "<ranking></ranking>"
2326 + "<enabled_listeners>"
2327 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
2328 + "</enabled_listeners>"
2329 + "<enabled_assistants>"
2330 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
2331 + "</enabled_assistants>"
2332 + "<dnd_apps>"
2333 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
2334 + "</dnd_apps>"
2335 + "</notification-policy>";
Julia Reynolds503ed942017-10-04 16:04:56 -04002336 mService.readPolicyXml(
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002337 new BufferedInputStream(new ByteArrayInputStream(upgradeXml.getBytes())), false);
Kristian Monsen05f34792018-04-09 10:27:16 +02002338 verify(mListeners, times(1)).readXml(any(), any());
2339 verify(mConditionProviders, times(1)).readXml(any(), any());
2340 verify(mAssistants, times(1)).readXml(any(), any());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002341
2342 // numbers are inflated for setup
2343 verify(mListeners, times(1)).migrateToXml();
2344 verify(mConditionProviders, times(1)).migrateToXml();
2345 verify(mAssistants, times(1)).migrateToXml();
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002346 verify(mAssistants, times(2)).ensureAssistant();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002347 }
2348
2349 @Test
2350 public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception {
2351 final String preupgradeXml = "<notification-policy version=\"1\">"
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002352 + "<ranking></ranking>"
2353 + "</notification-policy>";
Julia Reynolds503ed942017-10-04 16:04:56 -04002354 mService.readPolicyXml(
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002355 new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
Kristian Monsen05f34792018-04-09 10:27:16 +02002356 verify(mListeners, never()).readXml(any(), any());
2357 verify(mConditionProviders, never()).readXml(any(), any());
2358 verify(mAssistants, never()).readXml(any(), any());
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002359
2360 // numbers are inflated for setup
2361 verify(mListeners, times(2)).migrateToXml();
2362 verify(mConditionProviders, times(2)).migrateToXml();
2363 verify(mAssistants, times(2)).migrateToXml();
Julia Reynoldsd6d5a592018-04-02 11:03:32 -04002364 verify(mAssistants, times(2)).ensureAssistant();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04002365 }
2366
Beverlyd4f96492017-08-02 13:36:11 -04002367
2368 @Test
2369 public void testLocaleChangedCallsUpdateDefaultZenModeRules() throws Exception {
2370 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
Julia Reynolds503ed942017-10-04 16:04:56 -04002371 mService.mZenModeHelper = mZenModeHelper;
2372 mService.mLocaleChangeReceiver.onReceive(mContext,
Beverlyd4f96492017-08-02 13:36:11 -04002373 new Intent(Intent.ACTION_LOCALE_CHANGED));
2374
2375 verify(mZenModeHelper, times(1)).updateDefaultZenRules();
2376 }
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002377
2378 @Test
2379 public void testBumpFGImportance_noChannelChangePreOApp() throws Exception {
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002380 String preOPkg = PKG_N_MR1;
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002381 int preOUid = 145;
2382 final ApplicationInfo legacy = new ApplicationInfo();
2383 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
2384 when(mPackageManagerClient.getApplicationInfoAsUser(eq(preOPkg), anyInt(), anyInt()))
2385 .thenReturn(legacy);
2386 when(mPackageManagerClient.getPackageUidAsUser(eq(preOPkg), anyInt())).thenReturn(preOUid);
2387 getContext().setMockPackageManager(mPackageManagerClient);
2388
2389 Notification.Builder nb = new Notification.Builder(mContext,
2390 NotificationChannel.DEFAULT_CHANNEL_ID)
2391 .setContentTitle("foo")
2392 .setSmallIcon(android.R.drawable.sym_def_app_icon)
Julia Reynoldse5c60452018-04-30 14:41:36 -04002393 .setFlag(FLAG_FOREGROUND_SERVICE, true)
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002394 .setPriority(Notification.PRIORITY_MIN);
2395
2396 StatusBarNotification sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid,
2397 0, nb.build(), new UserHandle(preOUid), null, 0);
2398
2399 mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag",
2400 sbn.getId(), sbn.getNotification(), sbn.getUserId());
2401 waitForIdle();
2402 assertEquals(IMPORTANCE_LOW,
Julia Reynolds503ed942017-10-04 16:04:56 -04002403 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002404
2405 nb = new Notification.Builder(mContext)
2406 .setContentTitle("foo")
2407 .setSmallIcon(android.R.drawable.sym_def_app_icon)
Julia Reynoldse5c60452018-04-30 14:41:36 -04002408 .setFlag(FLAG_FOREGROUND_SERVICE, true)
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002409 .setPriority(Notification.PRIORITY_MIN);
2410
2411 sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid,
2412 0, nb.build(), new UserHandle(preOUid), null, 0);
2413
2414 mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag",
2415 sbn.getId(), sbn.getNotification(), sbn.getUserId());
2416 waitForIdle();
2417 assertEquals(IMPORTANCE_LOW,
Julia Reynolds503ed942017-10-04 16:04:56 -04002418 mService.getNotificationRecord(sbn.getKey()).getImportance());
Julia Reynolds8617e4e2017-09-18 16:52:37 -04002419
2420 NotificationChannel defaultChannel = mBinderService.getNotificationChannel(
2421 preOPkg, NotificationChannel.DEFAULT_CHANNEL_ID);
2422 assertEquals(IMPORTANCE_UNSPECIFIED, defaultChannel.getImportance());
2423 }
Julia Reynolds503ed942017-10-04 16:04:56 -04002424
2425 @Test
2426 public void testStats_updatedOnDirectReply() throws Exception {
2427 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2428 mService.addNotification(r);
2429
2430 mService.mNotificationDelegate.onNotificationDirectReplied(r.getKey());
2431 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasDirectReplied());
2432 }
2433
2434 @Test
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002435 public void testStats_updatedOnUserExpansion() throws Exception {
2436 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
Julia Reynolds503ed942017-10-04 16:04:56 -04002437 mService.addNotification(r);
2438
2439 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), true, true);
2440 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
2441 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), true, false);
2442 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
2443 }
2444
2445 @Test
Julia Reynolds84dc96b2017-11-14 09:51:01 -05002446 public void testStats_notUpdatedOnAutoExpansion() throws Exception {
2447 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2448 mService.addNotification(r);
2449
2450 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, true);
2451 assertFalse(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
2452 mService.mNotificationDelegate.onNotificationExpansionChanged(r.getKey(), false, false);
2453 assertFalse(mService.getNotificationRecord(r.getKey()).getStats().hasExpanded());
2454 }
2455
2456 @Test
Julia Reynolds503ed942017-10-04 16:04:56 -04002457 public void testStats_updatedOnViewSettings() throws Exception {
2458 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2459 mService.addNotification(r);
2460
2461 mService.mNotificationDelegate.onNotificationSettingsViewed(r.getKey());
2462 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasViewedSettings());
2463 }
2464
2465 @Test
2466 public void testStats_updatedOnVisibilityChanged() throws Exception {
2467 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2468 mService.addNotification(r);
2469
Dieter Hsud39f0d52018-04-14 02:08:30 +08002470 final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 1, 2, true);
Julia Reynolds503ed942017-10-04 16:04:56 -04002471 mService.mNotificationDelegate.onNotificationVisibilityChanged(
2472 new NotificationVisibility[] {nv}, new NotificationVisibility[]{});
2473 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasSeen());
2474 mService.mNotificationDelegate.onNotificationVisibilityChanged(
2475 new NotificationVisibility[] {}, new NotificationVisibility[]{nv});
2476 assertTrue(mService.getNotificationRecord(r.getKey()).getStats().hasSeen());
2477 }
2478
2479 @Test
2480 public void testStats_dismissalSurface() throws Exception {
2481 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2482 mService.addNotification(r);
2483
Dieter Hsud39f0d52018-04-14 02:08:30 +08002484 final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
Julia Reynolds503ed942017-10-04 16:04:56 -04002485 mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.sbn.getTag(),
Dieter Hsud39f0d52018-04-14 02:08:30 +08002486 r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD, nv);
Julia Reynolds503ed942017-10-04 16:04:56 -04002487 waitForIdle();
2488
2489 assertEquals(NotificationStats.DISMISSAL_AOD, r.getStats().getDismissalSurface());
2490 }
2491
2492 @Test
Julia Reynolds70aaea72018-07-13 13:38:34 -04002493 public void testApplyAdjustmentMultiUser() throws Exception {
Julia Reynolds503ed942017-10-04 16:04:56 -04002494 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2495 mService.addNotification(r);
2496 NotificationManagerService.WorkerHandler handler = mock(
2497 NotificationManagerService.WorkerHandler.class);
2498 mService.setHandler(handler);
2499
Julia Reynolds70aaea72018-07-13 13:38:34 -04002500 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(false);
2501
Julia Reynolds503ed942017-10-04 16:04:56 -04002502 Bundle signals = new Bundle();
2503 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
Julia Reynolds70aaea72018-07-13 13:38:34 -04002504 USER_SENTIMENT_NEGATIVE);
2505 Adjustment adjustment = new Adjustment(
2506 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2507 mBinderService.applyAdjustmentFromAssistant(null, adjustment);
2508
2509 waitForIdle();
2510
2511 verify(handler, timeout(300).times(0)).scheduleSendRankingUpdate();
2512 }
2513
2514 @Test
Julia Reynoldsefcdff42018-08-09 09:42:56 -04002515 public void testAssistantIBlockingTriggersCancel() throws Exception {
2516 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2517 mService.addNotification(r);
2518 NotificationManagerService.WorkerHandler handler = mock(
2519 NotificationManagerService.WorkerHandler.class);
2520 mService.setHandler(handler);
2521
2522 Bundle signals = new Bundle();
2523 signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE);
2524 Adjustment adjustment = new Adjustment(
2525 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2526 when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
2527 mBinderService.applyAdjustmentFromAssistant(null, adjustment);
2528
2529 waitForIdle();
2530
2531 verify(handler, timeout(300).times(0)).scheduleSendRankingUpdate();
2532 verify(handler, times(1)).scheduleCancelNotification(any());
2533 }
2534
2535 @Test
Julia Reynolds70aaea72018-07-13 13:38:34 -04002536 public void testApplyEnqueuedAdjustmentFromAssistant_singleUser() throws Exception {
2537 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2538 mService.addEnqueuedNotification(r);
2539 NotificationManagerService.WorkerHandler handler = mock(
2540 NotificationManagerService.WorkerHandler.class);
2541 mService.setHandler(handler);
2542 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
2543
2544 Bundle signals = new Bundle();
2545 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
2546 USER_SENTIMENT_NEGATIVE);
2547 Adjustment adjustment = new Adjustment(
2548 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2549 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
2550
2551 assertEquals(USER_SENTIMENT_NEGATIVE, r.getUserSentiment());
2552 }
2553
2554 @Test
2555 public void testApplyEnqueuedAdjustmentFromAssistant_crossUser() throws Exception {
2556 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2557 mService.addEnqueuedNotification(r);
2558 NotificationManagerService.WorkerHandler handler = mock(
2559 NotificationManagerService.WorkerHandler.class);
2560 mService.setHandler(handler);
2561 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(false);
2562
2563 Bundle signals = new Bundle();
2564 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
2565 USER_SENTIMENT_NEGATIVE);
2566 Adjustment adjustment = new Adjustment(
2567 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2568 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
2569
2570 assertEquals(USER_SENTIMENT_NEUTRAL, r.getUserSentiment());
2571
2572 waitForIdle();
2573
2574 verify(handler, timeout(300).times(0)).scheduleSendRankingUpdate();
2575 }
2576
2577 @Test
2578 public void testUserSentimentChangeTriggersUpdate() throws Exception {
2579 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2580 mService.addNotification(r);
2581 NotificationManagerService.WorkerHandler handler = mock(
2582 NotificationManagerService.WorkerHandler.class);
2583 mService.setHandler(handler);
2584 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
2585
2586 Bundle signals = new Bundle();
2587 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
2588 USER_SENTIMENT_NEGATIVE);
Julia Reynolds503ed942017-10-04 16:04:56 -04002589 Adjustment adjustment = new Adjustment(
2590 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2591 mBinderService.applyAdjustmentFromAssistant(null, adjustment);
2592
2593 waitForIdle();
2594
2595 verify(handler, timeout(300).times(1)).scheduleSendRankingUpdate();
2596 }
Julia Reynolds7bcb57b2018-01-22 10:37:58 -05002597
2598 @Test
Julia Reynolds666ccf02018-06-18 10:19:20 -04002599 public void testTooLateAdjustmentTriggersUpdate() throws Exception {
2600 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2601 mService.addNotification(r);
2602 NotificationManagerService.WorkerHandler handler = mock(
2603 NotificationManagerService.WorkerHandler.class);
2604 mService.setHandler(handler);
Julia Reynolds70aaea72018-07-13 13:38:34 -04002605 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
Julia Reynolds666ccf02018-06-18 10:19:20 -04002606
2607 Bundle signals = new Bundle();
2608 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
Julia Reynolds70aaea72018-07-13 13:38:34 -04002609 USER_SENTIMENT_NEGATIVE);
Julia Reynolds666ccf02018-06-18 10:19:20 -04002610 Adjustment adjustment = new Adjustment(
2611 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2612 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
2613
2614 waitForIdle();
2615
2616 verify(handler, timeout(300).times(1)).scheduleSendRankingUpdate();
2617 }
2618
2619 @Test
2620 public void testEnqueuedAdjustmentAppliesAdjustments() throws Exception {
2621 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
2622 mService.addEnqueuedNotification(r);
2623 NotificationManagerService.WorkerHandler handler = mock(
2624 NotificationManagerService.WorkerHandler.class);
2625 mService.setHandler(handler);
Julia Reynolds70aaea72018-07-13 13:38:34 -04002626 when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
Julia Reynolds666ccf02018-06-18 10:19:20 -04002627
2628 Bundle signals = new Bundle();
2629 signals.putInt(Adjustment.KEY_USER_SENTIMENT,
Julia Reynolds70aaea72018-07-13 13:38:34 -04002630 USER_SENTIMENT_NEGATIVE);
Julia Reynolds666ccf02018-06-18 10:19:20 -04002631 Adjustment adjustment = new Adjustment(
2632 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
2633 mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
2634
Julia Reynolds70aaea72018-07-13 13:38:34 -04002635 assertEquals(USER_SENTIMENT_NEGATIVE,
Julia Reynolds666ccf02018-06-18 10:19:20 -04002636 r.getUserSentiment());
2637 }
2638
2639 @Test
Julia Reynolds7bcb57b2018-01-22 10:37:58 -05002640 public void testRecents() throws Exception {
2641 Set<NotifyingApp> expected = new HashSet<>();
2642
2643 final NotificationRecord oldest = new NotificationRecord(mContext,
2644 generateSbn("p", 1000, 9, 0), mTestNotificationChannel);
2645 mService.logRecentLocked(oldest);
2646 for (int i = 1; i <= 5; i++) {
2647 NotificationRecord r = new NotificationRecord(mContext,
2648 generateSbn("p" + i, i, i*100, 0), mTestNotificationChannel);
2649 expected.add(new NotifyingApp()
2650 .setPackage(r.sbn.getPackageName())
2651 .setUid(r.sbn.getUid())
2652 .setLastNotified(r.sbn.getPostTime()));
2653 mService.logRecentLocked(r);
2654 }
2655
2656 List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
2657 assertTrue(apps.size() == 5);
2658 for (NotifyingApp actual : apps) {
2659 assertTrue("got unexpected result: " + actual, expected.contains(actual));
2660 }
2661 }
2662
2663 @Test
2664 public void testRecentsNoDuplicatePackages() throws Exception {
2665 final NotificationRecord p1 = new NotificationRecord(mContext, generateSbn("p", 1, 1000, 0),
2666 mTestNotificationChannel);
2667 final NotificationRecord p2 = new NotificationRecord(mContext, generateSbn("p", 1, 2000, 0),
2668 mTestNotificationChannel);
2669
2670 mService.logRecentLocked(p1);
2671 mService.logRecentLocked(p2);
2672
2673 List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
2674 assertTrue(apps.size() == 1);
2675 NotifyingApp expected = new NotifyingApp().setPackage("p").setUid(1).setLastNotified(2000);
2676 assertEquals(expected, apps.get(0));
2677 }
2678
2679 @Test
2680 public void testRecentsWithDuplicatePackage() throws Exception {
2681 Set<NotifyingApp> expected = new HashSet<>();
2682
2683 final NotificationRecord oldest = new NotificationRecord(mContext,
2684 generateSbn("p", 1000, 9, 0), mTestNotificationChannel);
2685 mService.logRecentLocked(oldest);
2686 for (int i = 1; i <= 5; i++) {
2687 NotificationRecord r = new NotificationRecord(mContext,
2688 generateSbn("p" + i, i, i*100, 0), mTestNotificationChannel);
2689 expected.add(new NotifyingApp()
2690 .setPackage(r.sbn.getPackageName())
2691 .setUid(r.sbn.getUid())
2692 .setLastNotified(r.sbn.getPostTime()));
2693 mService.logRecentLocked(r);
2694 }
2695 NotificationRecord r = new NotificationRecord(mContext,
2696 generateSbn("p" + 3, 3, 300000, 0), mTestNotificationChannel);
2697 expected.remove(new NotifyingApp()
2698 .setPackage(r.sbn.getPackageName())
2699 .setUid(3)
2700 .setLastNotified(300));
2701 NotifyingApp newest = new NotifyingApp()
2702 .setPackage(r.sbn.getPackageName())
2703 .setUid(r.sbn.getUid())
2704 .setLastNotified(r.sbn.getPostTime());
2705 expected.add(newest);
2706 mService.logRecentLocked(r);
2707
2708 List<NotifyingApp> apps = mBinderService.getRecentNotifyingAppsForUser(0).getList();
2709 assertTrue(apps.size() == 5);
2710 for (NotifyingApp actual : apps) {
2711 assertTrue("got unexpected result: " + actual, expected.contains(actual));
2712 }
2713 assertEquals(newest, apps.get(0));
2714 }
2715
2716 @Test
2717 public void testRecentsMultiuser() throws Exception {
2718 final NotificationRecord user1 = new NotificationRecord(mContext,
2719 generateSbn("p", 1000, 9, 1), mTestNotificationChannel);
2720 mService.logRecentLocked(user1);
2721
2722 final NotificationRecord user2 = new NotificationRecord(mContext,
2723 generateSbn("p2", 100000, 9999, 2), mTestNotificationChannel);
2724 mService.logRecentLocked(user2);
2725
2726 assertEquals(0, mBinderService.getRecentNotifyingAppsForUser(0).getList().size());
2727 assertEquals(1, mBinderService.getRecentNotifyingAppsForUser(1).getList().size());
2728 assertEquals(1, mBinderService.getRecentNotifyingAppsForUser(2).getList().size());
2729
2730 assertTrue(mBinderService.getRecentNotifyingAppsForUser(2).getList().contains(
2731 new NotifyingApp()
2732 .setPackage(user2.sbn.getPackageName())
2733 .setUid(user2.sbn.getUid())
2734 .setLastNotified(user2.sbn.getPostTime())));
2735 }
Julia Reynoldsd78263d2018-01-30 10:40:41 -05002736
2737 @Test
2738 public void testRestore() throws Exception {
2739 int systemChecks = mService.countSystemChecks;
2740 mBinderService.applyRestore(null, UserHandle.USER_SYSTEM);
2741 assertEquals(1, mService.countSystemChecks - systemChecks);
2742 }
2743
2744 @Test
2745 public void testBackup() throws Exception {
2746 int systemChecks = mService.countSystemChecks;
2747 mBinderService.getBackupPayload(1);
2748 assertEquals(1, mService.countSystemChecks - systemChecks);
2749 }
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002750
2751 @Test
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002752 public void updateUriPermissions_update() throws Exception {
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002753 NotificationChannel c = new NotificationChannel(
2754 TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
2755 c.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
2756 Message message1 = new Message("", 0, "");
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002757 message1.setData("",
2758 ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1));
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002759 Message message2 = new Message("", 1, "");
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002760 message2.setData("",
2761 ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 2));
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002762
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002763 Notification.Builder nbA = new Notification.Builder(mContext, c.getId())
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002764 .setContentTitle("foo")
2765 .setSmallIcon(android.R.drawable.sym_def_app_icon)
2766 .setStyle(new Notification.MessagingStyle("")
2767 .addMessage(message1)
2768 .addMessage(message2));
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002769 NotificationRecord recordA = new NotificationRecord(mContext, new StatusBarNotification(
2770 PKG, PKG, 0, "tag", mUid, 0, nbA.build(), new UserHandle(mUid), null, 0), c);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002771
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002772 // First post means we grant access to both
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07002773 reset(mUgm);
2774 reset(mUgmInternal);
2775 when(mUgmInternal.newUriPermissionOwner(any())).thenReturn(new Binder());
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002776 mService.updateUriPermissions(recordA, null, mContext.getPackageName(),
2777 UserHandle.USER_SYSTEM);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07002778 verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002779 eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07002780 verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002781 eq(message2.getDataUri()), anyInt(), anyInt(), anyInt());
2782
2783 Notification.Builder nbB = new Notification.Builder(mContext, c.getId())
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002784 .setContentTitle("foo")
2785 .setSmallIcon(android.R.drawable.sym_def_app_icon)
2786 .setStyle(new Notification.MessagingStyle("").addMessage(message2));
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002787 NotificationRecord recordB = new NotificationRecord(mContext, new StatusBarNotification(PKG,
2788 PKG, 0, "tag", mUid, 0, nbB.build(), new UserHandle(mUid), null, 0), c);
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002789
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002790 // Update means we drop access to first
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07002791 reset(mUgmInternal);
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002792 mService.updateUriPermissions(recordB, recordA, mContext.getPackageName(),
2793 UserHandle.USER_SYSTEM);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07002794 verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(),
2795 eq(message1.getDataUri()), anyInt(), anyInt());
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002796
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002797 // Update back means we grant access to first again
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07002798 reset(mUgm);
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002799 mService.updateUriPermissions(recordA, recordB, mContext.getPackageName(),
2800 UserHandle.USER_SYSTEM);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07002801 verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002802 eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002803
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002804 // And update to empty means we drop everything
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07002805 reset(mUgmInternal);
Jeff Sharkey6a97cc32018-04-17 12:16:20 -06002806 mService.updateUriPermissions(null, recordB, mContext.getPackageName(),
2807 UserHandle.USER_SYSTEM);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07002808 verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(), eq(null),
Julia Reynoldse0d711f2017-09-01 08:50:47 -04002809 anyInt(), anyInt());
2810 }
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05002811
2812 @Test
Robin Leed107af62018-04-27 13:55:56 +02002813 public void testVisitUris() throws Exception {
2814 final Uri audioContents = Uri.parse("content://com.example/audio");
2815 final Uri backgroundImage = Uri.parse("content://com.example/background");
2816
2817 Bundle extras = new Bundle();
2818 extras.putParcelable(Notification.EXTRA_AUDIO_CONTENTS_URI, audioContents);
2819 extras.putString(Notification.EXTRA_BACKGROUND_IMAGE_URI, backgroundImage.toString());
2820
2821 Notification n = new Notification.Builder(mContext, "a")
2822 .setContentTitle("notification with uris")
2823 .setSmallIcon(android.R.drawable.sym_def_app_icon)
2824 .addExtras(extras)
2825 .build();
2826
2827 Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
2828 n.visitUris(visitor);
2829 verify(visitor, times(1)).accept(eq(audioContents));
2830 verify(visitor, times(1)).accept(eq(backgroundImage));
2831 }
2832
2833 @Test
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05002834 public void testSetNotificationPolicy_preP_setOldFields() {
2835 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2836 mService.mZenModeHelper = mZenModeHelper;
2837 NotificationManager.Policy userPolicy =
2838 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2839 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2840
2841 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2842 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF);
2843
2844 int expected = SUPPRESSED_EFFECT_BADGE
2845 | SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF
Julia Reynoldseac2da22018-04-12 10:48:46 -04002846 | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_LIGHTS
2847 | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05002848 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
2849
2850 assertEquals(expected, actual);
2851 }
2852
2853 @Test
2854 public void testSetNotificationPolicy_preP_setNewFields() {
2855 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2856 mService.mZenModeHelper = mZenModeHelper;
2857 NotificationManager.Policy userPolicy =
2858 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2859 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2860
2861 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2862 SUPPRESSED_EFFECT_NOTIFICATION_LIST);
2863
2864 int expected = SUPPRESSED_EFFECT_BADGE;
2865 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
2866
2867 assertEquals(expected, actual);
2868 }
2869
2870 @Test
2871 public void testSetNotificationPolicy_preP_setOldNewFields() {
2872 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2873 mService.mZenModeHelper = mZenModeHelper;
2874 NotificationManager.Policy userPolicy =
2875 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2876 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2877
2878 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2879 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_STATUS_BAR);
2880
2881 int expected =
2882 SUPPRESSED_EFFECT_BADGE | SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_PEEK;
2883 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, O_MR1);
2884
2885 assertEquals(expected, actual);
2886 }
2887
2888 @Test
2889 public void testSetNotificationPolicy_P_setOldFields() {
2890 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2891 mService.mZenModeHelper = mZenModeHelper;
2892 NotificationManager.Policy userPolicy =
2893 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2894 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2895
2896 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2897 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF);
2898
2899 int expected = SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF
2900 | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_AMBIENT
2901 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
2902 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
2903
2904 assertEquals(expected, actual);
2905 }
2906
2907 @Test
2908 public void testSetNotificationPolicy_P_setNewFields() {
2909 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2910 mService.mZenModeHelper = mZenModeHelper;
2911 NotificationManager.Policy userPolicy =
2912 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2913 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2914
2915 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2916 SUPPRESSED_EFFECT_NOTIFICATION_LIST | SUPPRESSED_EFFECT_AMBIENT
2917 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT);
2918
2919 int expected = SUPPRESSED_EFFECT_NOTIFICATION_LIST | SUPPRESSED_EFFECT_SCREEN_OFF
2920 | SUPPRESSED_EFFECT_AMBIENT | SUPPRESSED_EFFECT_LIGHTS
2921 | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
2922 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
2923
2924 assertEquals(expected, actual);
2925 }
2926
2927 @Test
2928 public void testSetNotificationPolicy_P_setOldNewFields() {
2929 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
2930 mService.mZenModeHelper = mZenModeHelper;
2931 NotificationManager.Policy userPolicy =
2932 new NotificationManager.Policy(0, 0, 0, SUPPRESSED_EFFECT_BADGE);
2933 when(mZenModeHelper.getNotificationPolicy()).thenReturn(userPolicy);
2934
2935 NotificationManager.Policy appPolicy = new NotificationManager.Policy(0, 0, 0,
2936 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_STATUS_BAR);
2937
2938 int expected = SUPPRESSED_EFFECT_STATUS_BAR;
2939 int actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
2940
2941 assertEquals(expected, actual);
2942
2943 appPolicy = new NotificationManager.Policy(0, 0, 0,
2944 SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_AMBIENT
2945 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT);
2946
2947 expected = SUPPRESSED_EFFECT_SCREEN_OFF | SUPPRESSED_EFFECT_AMBIENT
2948 | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
2949 actual = mService.calculateSuppressedVisualEffects(appPolicy, userPolicy, P);
2950
2951 assertEquals(expected, actual);
2952 }
Julia Reynolds7217dc92018-03-07 12:12:09 -05002953
2954 @Test
Julia Reynoldse5c60452018-04-30 14:41:36 -04002955 public void testVisualDifference_foreground() {
2956 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2957 .setContentTitle("foo");
2958 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2959 nb1.build(), new UserHandle(mUid), null, 0);
2960 NotificationRecord r1 =
2961 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2962
2963 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2964 .setFlag(FLAG_FOREGROUND_SERVICE, true)
2965 .setContentTitle("bar");
2966 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2967 nb2.build(), new UserHandle(mUid), null, 0);
2968 NotificationRecord r2 =
2969 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2970
2971 assertFalse(mService.isVisuallyInterruptive(r1, r2));
2972 }
2973
2974 @Test
Julia Reynolds7217dc92018-03-07 12:12:09 -05002975 public void testVisualDifference_diffTitle() {
2976 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2977 .setContentTitle("foo");
2978 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2979 nb1.build(), new UserHandle(mUid), null, 0);
2980 NotificationRecord r1 =
2981 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
2982
2983 Notification.Builder nb2 = new Notification.Builder(mContext, "")
2984 .setContentTitle("bar");
2985 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2986 nb2.build(), new UserHandle(mUid), null, 0);
2987 NotificationRecord r2 =
2988 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
2989
2990 assertTrue(mService.isVisuallyInterruptive(r1, r2));
2991 }
2992
2993 @Test
Dan Sandler7d67bd42018-05-15 14:06:38 -04002994 public void testVisualDifference_inboxStyle() {
2995 Notification.Builder nb1 = new Notification.Builder(mContext, "")
2996 .setStyle(new Notification.InboxStyle()
2997 .addLine("line1").addLine("line2"));
2998 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
2999 nb1.build(), new UserHandle(mUid), null, 0);
3000 NotificationRecord r1 =
3001 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3002
3003 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3004 .setStyle(new Notification.InboxStyle()
3005 .addLine("line1").addLine("line2_changed"));
3006 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3007 nb2.build(), new UserHandle(mUid), null, 0);
3008 NotificationRecord r2 =
3009 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3010
3011 assertTrue(mService.isVisuallyInterruptive(r1, r2)); // line 2 changed unnoticed
3012
3013 Notification.Builder nb3 = new Notification.Builder(mContext, "")
3014 .setStyle(new Notification.InboxStyle()
3015 .addLine("line1"));
3016 StatusBarNotification sbn3 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3017 nb3.build(), new UserHandle(mUid), null, 0);
3018 NotificationRecord r3 =
3019 new NotificationRecord(mContext, sbn3, mock(NotificationChannel.class));
3020
3021 assertTrue(mService.isVisuallyInterruptive(r1, r3)); // line 2 removed unnoticed
3022
3023 Notification.Builder nb4 = new Notification.Builder(mContext, "")
3024 .setStyle(new Notification.InboxStyle()
3025 .addLine("line1").addLine("line2").addLine("line3"));
3026 StatusBarNotification sbn4 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3027 nb4.build(), new UserHandle(mUid), null, 0);
3028 NotificationRecord r4 =
3029 new NotificationRecord(mContext, sbn4, mock(NotificationChannel.class));
3030
3031 assertTrue(mService.isVisuallyInterruptive(r1, r4)); // line 3 added unnoticed
3032
3033 Notification.Builder nb5 = new Notification.Builder(mContext, "")
3034 .setContentText("not an inbox");
3035 StatusBarNotification sbn5 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3036 nb5.build(), new UserHandle(mUid), null, 0);
3037 NotificationRecord r5 =
3038 new NotificationRecord(mContext, sbn5, mock(NotificationChannel.class));
3039
3040 assertTrue(mService.isVisuallyInterruptive(r1, r5)); // changed Styles, went unnoticed
3041 }
3042
3043 @Test
Julia Reynolds7217dc92018-03-07 12:12:09 -05003044 public void testVisualDifference_diffText() {
3045 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3046 .setContentText("foo");
3047 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3048 nb1.build(), new UserHandle(mUid), null, 0);
3049 NotificationRecord r1 =
3050 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3051
3052 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3053 .setContentText("bar");
3054 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3055 nb2.build(), new UserHandle(mUid), null, 0);
3056 NotificationRecord r2 =
3057 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3058
3059 assertTrue(mService.isVisuallyInterruptive(r1, r2));
3060 }
3061
3062 @Test
Dan Sandler7d67bd42018-05-15 14:06:38 -04003063 public void testVisualDifference_sameText() {
3064 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3065 .setContentText("foo");
3066 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3067 nb1.build(), new UserHandle(mUid), null, 0);
3068 NotificationRecord r1 =
3069 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3070
3071 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3072 .setContentText("foo");
3073 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3074 nb2.build(), new UserHandle(mUid), null, 0);
3075 NotificationRecord r2 =
3076 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3077
3078 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3079 }
3080
3081 @Test
3082 public void testVisualDifference_sameTextButStyled() {
3083 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3084 .setContentText(Html.fromHtml("<b>foo</b>"));
3085 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3086 nb1.build(), new UserHandle(mUid), null, 0);
3087 NotificationRecord r1 =
3088 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3089
3090 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3091 .setContentText(Html.fromHtml("<b>foo</b>"));
3092 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3093 nb2.build(), new UserHandle(mUid), null, 0);
3094 NotificationRecord r2 =
3095 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3096
3097 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3098 }
3099
3100 @Test
3101 public void testVisualDifference_diffTextButStyled() {
3102 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3103 .setContentText(Html.fromHtml("<b>foo</b>"));
3104 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3105 nb1.build(), new UserHandle(mUid), null, 0);
3106 NotificationRecord r1 =
3107 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3108
3109 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3110 .setContentText(Html.fromHtml("<b>bar</b>"));
3111 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3112 nb2.build(), new UserHandle(mUid), null, 0);
3113 NotificationRecord r2 =
3114 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3115
3116 assertTrue(mService.isVisuallyInterruptive(r1, r2));
3117 }
3118
3119 @Test
Julia Reynolds7217dc92018-03-07 12:12:09 -05003120 public void testVisualDifference_diffProgress() {
3121 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3122 .setProgress(100, 90, false);
3123 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3124 nb1.build(), new UserHandle(mUid), null, 0);
3125 NotificationRecord r1 =
3126 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3127
3128 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3129 .setProgress(100, 100, false);
3130 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3131 nb2.build(), new UserHandle(mUid), null, 0);
3132 NotificationRecord r2 =
3133 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3134
3135 assertTrue(mService.isVisuallyInterruptive(r1, r2));
3136 }
3137
3138 @Test
3139 public void testVisualDifference_diffProgressNotDone() {
3140 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3141 .setProgress(100, 90, false);
3142 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3143 nb1.build(), new UserHandle(mUid), null, 0);
3144 NotificationRecord r1 =
3145 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3146
3147 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3148 .setProgress(100, 91, false);
3149 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3150 nb2.build(), new UserHandle(mUid), null, 0);
3151 NotificationRecord r2 =
3152 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3153
3154 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3155 }
Beverly5a20a5e2018-03-06 15:02:44 -05003156
3157 @Test
Dan Sandler7d67bd42018-05-15 14:06:38 -04003158 public void testVisualDifference_sameProgressStillDone() {
3159 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3160 .setProgress(100, 100, false);
3161 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3162 nb1.build(), new UserHandle(mUid), null, 0);
3163 NotificationRecord r1 =
3164 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3165
3166 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3167 .setProgress(100, 100, false);
3168 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3169 nb2.build(), new UserHandle(mUid), null, 0);
3170 NotificationRecord r2 =
3171 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3172
3173 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3174 }
3175
3176 @Test
Julia Reynoldsa4fb9da2018-06-04 12:27:58 -04003177 public void testVisualDifference_summary() {
3178 Notification.Builder nb1 = new Notification.Builder(mContext, "")
3179 .setGroup("bananas")
3180 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
3181 .setContentText("foo");
3182 StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3183 nb1.build(), new UserHandle(mUid), null, 0);
3184 NotificationRecord r1 =
3185 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
3186
3187 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3188 .setGroup("bananas")
3189 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
3190 .setContentText("bar");
3191 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3192 nb2.build(), new UserHandle(mUid), null, 0);
3193 NotificationRecord r2 =
3194 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3195
3196 assertFalse(mService.isVisuallyInterruptive(r1, r2));
3197 }
3198
3199 @Test
Julia Reynolds760fa762018-06-19 15:39:23 -04003200 public void testVisualDifference_summaryNewNotification() {
3201 Notification.Builder nb2 = new Notification.Builder(mContext, "")
3202 .setGroup("bananas")
3203 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
3204 .setContentText("bar");
3205 StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
3206 nb2.build(), new UserHandle(mUid), null, 0);
3207 NotificationRecord r2 =
3208 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
3209
3210 assertFalse(mService.isVisuallyInterruptive(null, r2));
3211 }
3212
3213 @Test
Beverly5a20a5e2018-03-06 15:02:44 -05003214 public void testHideAndUnhideNotificationsOnSuspendedPackageBroadcast() {
3215 // post 2 notification from this package
3216 final NotificationRecord notif1 = generateNotificationRecord(
3217 mTestNotificationChannel, 1, null, true);
3218 final NotificationRecord notif2 = generateNotificationRecord(
3219 mTestNotificationChannel, 2, null, false);
3220 mService.addNotification(notif1);
3221 mService.addNotification(notif2);
3222
3223 // on broadcast, hide the 2 notifications
3224 mService.simulatePackageSuspendBroadcast(true, PKG);
3225 ArgumentCaptor<List> captorHide = ArgumentCaptor.forClass(List.class);
3226 verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
3227 assertEquals(2, captorHide.getValue().size());
3228
3229 // on broadcast, unhide the 2 notifications
3230 mService.simulatePackageSuspendBroadcast(false, PKG);
3231 ArgumentCaptor<List> captorUnhide = ArgumentCaptor.forClass(List.class);
3232 verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
3233 assertEquals(2, captorUnhide.getValue().size());
3234 }
3235
3236 @Test
3237 public void testNoNotificationsHiddenOnSuspendedPackageBroadcast() {
3238 // post 2 notification from this package
3239 final NotificationRecord notif1 = generateNotificationRecord(
3240 mTestNotificationChannel, 1, null, true);
3241 final NotificationRecord notif2 = generateNotificationRecord(
3242 mTestNotificationChannel, 2, null, false);
3243 mService.addNotification(notif1);
3244 mService.addNotification(notif2);
3245
3246 // on broadcast, nothing is hidden since no notifications are of package "test_package"
3247 mService.simulatePackageSuspendBroadcast(true, "test_package");
3248 ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
3249 verify(mListeners, times(1)).notifyHiddenLocked(captor.capture());
3250 assertEquals(0, captor.getValue().size());
3251 }
Kristian Monsen05f34792018-04-09 10:27:16 +02003252
3253 @Test
3254 public void testCanUseManagedServicesLowRamNoWatchNullPkg() {
3255 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3256 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3257 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3258 .thenReturn(new String[] {"a", "b", "c"});
3259 when(mContext.getResources()).thenReturn(mResources);
3260
3261 assertEquals(false, mService.canUseManagedServices(null));
3262 }
3263
3264 @Test
3265 public void testCanUseManagedServicesLowRamNoWatchValidPkg() {
3266 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3267 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3268 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3269 .thenReturn(new String[] {"a", "b", "c"});
3270 when(mContext.getResources()).thenReturn(mResources);
3271
3272 assertEquals(true, mService.canUseManagedServices("b"));
3273 }
3274
3275 @Test
3276 public void testCanUseManagedServicesLowRamNoWatchNoValidPkg() {
3277 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3278 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3279 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3280 .thenReturn(new String[] {"a", "b", "c"});
3281 when(mContext.getResources()).thenReturn(mResources);
3282
3283 assertEquals(false, mService.canUseManagedServices("d"));
3284 }
3285
3286 @Test
3287 public void testCanUseManagedServicesLowRamWatchNoValidPkg() {
3288 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
3289 when(mActivityManager.isLowRamDevice()).thenReturn(true);
3290 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3291 .thenReturn(new String[] {"a", "b", "c"});
3292 when(mContext.getResources()).thenReturn(mResources);
3293
3294 assertEquals(true, mService.canUseManagedServices("d"));
3295 }
3296
3297 @Test
3298 public void testCanUseManagedServicesNoLowRamNoWatchValidPkg() {
3299 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
3300 when(mActivityManager.isLowRamDevice()).thenReturn(false);
3301 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3302 .thenReturn(new String[] {"a", "b", "c"});
3303 when(mContext.getResources()).thenReturn(mResources);
3304
3305 assertEquals(true, mService.canUseManagedServices("d"));
3306 }
3307
3308 @Test
3309 public void testCanUseManagedServicesNoLowRamWatchValidPkg() {
3310 when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(true);
3311 when(mActivityManager.isLowRamDevice()).thenReturn(false);
3312 when(mResources.getStringArray(R.array.config_allowedManagedServicesOnLowRamDevices))
3313 .thenReturn(new String[] {"a", "b", "c"});
3314 when(mContext.getResources()).thenReturn(mResources);
3315
3316 assertEquals(true, mService.canUseManagedServices("d"));
3317 }
Julia Reynoldsb3c68ff2018-05-22 14:58:39 -04003318
3319 @Test
3320 public void testOnNotificationVisibilityChanged_triggersInterruptionUsageStat() {
3321 final NotificationRecord r = generateNotificationRecord(
3322 mTestNotificationChannel, 1, null, true);
3323 r.setTextChanged(true);
3324 mService.addNotification(r);
3325
3326 mService.mNotificationDelegate.onNotificationVisibilityChanged(new NotificationVisibility[]
3327 {NotificationVisibility.obtain(r.getKey(), 1, 1, true)},
3328 new NotificationVisibility[]{});
3329
3330 verify(mAppUsageStats).reportInterruptiveNotification(anyString(), anyString(), anyInt());
3331 }
3332
3333 @Test
3334 public void testSetNotificationsShownFromListener_triggersInterruptionUsageStat()
3335 throws RemoteException {
3336 final NotificationRecord r = generateNotificationRecord(
3337 mTestNotificationChannel, 1, null, true);
3338 r.setTextChanged(true);
3339 mService.addNotification(r);
3340
3341 mBinderService.setNotificationsShownFromListener(null, new String[] {r.getKey()});
3342
3343 verify(mAppUsageStats).reportInterruptiveNotification(anyString(), anyString(), anyInt());
3344 }
3345
3346 @Test
3347 public void testMybeRecordInterruptionLocked_doesNotRecordTwice()
3348 throws RemoteException {
3349 final NotificationRecord r = generateNotificationRecord(
3350 mTestNotificationChannel, 1, null, true);
3351 r.setInterruptive(true);
3352 mService.addNotification(r);
3353
3354 mService.maybeRecordInterruptionLocked(r);
3355 mService.maybeRecordInterruptionLocked(r);
3356
3357 verify(mAppUsageStats, times(1)).reportInterruptiveNotification(
3358 anyString(), anyString(), anyInt());
3359 }
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -05003360}