1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui; 18 19 import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL; 20 21 import static junit.framework.Assert.assertEquals; 22 import static junit.framework.Assert.assertNull; 23 import static junit.framework.TestCase.fail; 24 25 import static org.junit.Assert.assertFalse; 26 import static org.junit.Assert.assertTrue; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.verify; 29 import static org.mockito.Mockito.when; 30 31 import android.annotation.UserIdInt; 32 import android.app.AppOpsManager; 33 import android.app.Notification; 34 import android.app.NotificationManager; 35 import android.os.Bundle; 36 import android.os.Handler; 37 import android.os.UserHandle; 38 import android.service.notification.StatusBarNotification; 39 import android.testing.AndroidTestingRunner; 40 import android.testing.TestableLooper; 41 import android.widget.RemoteViews; 42 43 import androidx.test.filters.SmallTest; 44 45 import com.android.internal.messages.nano.SystemMessageProto; 46 import com.android.systemui.appops.AppOpsController; 47 import com.android.systemui.statusbar.notification.NotificationEntryListener; 48 import com.android.systemui.statusbar.notification.NotificationEntryManager; 49 import com.android.systemui.statusbar.notification.collection.NotifPipeline; 50 import com.android.systemui.statusbar.notification.collection.NotificationEntry; 51 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; 52 import com.android.systemui.util.time.FakeSystemClock; 53 54 import org.junit.Before; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 import org.mockito.ArgumentCaptor; 58 import org.mockito.Mock; 59 import org.mockito.MockitoAnnotations; 60 61 @SmallTest 62 @RunWith(AndroidTestingRunner.class) 63 @TestableLooper.RunWithLooper 64 public class ForegroundServiceControllerTest extends SysuiTestCase { 65 private ForegroundServiceController mFsc; 66 private ForegroundServiceNotificationListener mListener; 67 private NotificationEntryListener mEntryListener; 68 private final FakeSystemClock mClock = new FakeSystemClock(); 69 @Mock private NotificationEntryManager mEntryManager; 70 @Mock private AppOpsController mAppOpsController; 71 @Mock private Handler mMainHandler; 72 @Mock private NotifPipeline mNotifPipeline; 73 74 @Before setUp()75 public void setUp() throws Exception { 76 // allow the TestLooper to be asserted as the main thread these tests 77 allowTestableLooperAsMainThread(); 78 79 MockitoAnnotations.initMocks(this); 80 mFsc = new ForegroundServiceController(mAppOpsController, mMainHandler); 81 mListener = new ForegroundServiceNotificationListener( 82 mContext, mFsc, mEntryManager, mNotifPipeline, mClock); 83 ArgumentCaptor<NotificationEntryListener> entryListenerCaptor = 84 ArgumentCaptor.forClass(NotificationEntryListener.class); 85 verify(mEntryManager).addNotificationEntryListener( 86 entryListenerCaptor.capture()); 87 mEntryListener = entryListenerCaptor.getValue(); 88 } 89 90 @Test testAppOpsChangedCalledFromBgThread()91 public void testAppOpsChangedCalledFromBgThread() { 92 try { 93 // WHEN onAppOpChanged is called from a different thread than the MainLooper 94 disallowTestableLooperAsMainThread(); 95 NotificationEntry entry = createFgEntry(); 96 mFsc.onAppOpChanged( 97 AppOpsManager.OP_CAMERA, 98 entry.getSbn().getUid(), 99 entry.getSbn().getPackageName(), 100 true); 101 102 // This test is run on the TestableLooper, which is not the MainLooper, so 103 // we expect an exception to be thrown 104 fail("onAppOpChanged shouldn't be allowed to be called from a bg thread."); 105 } catch (IllegalStateException e) { 106 // THEN expect an exception 107 } 108 } 109 110 @Test testAppOpsCRUD()111 public void testAppOpsCRUD() { 112 // no crash on remove that doesn't exist 113 mFsc.onAppOpChanged(9, 1000, "pkg1", false); 114 assertNull(mFsc.getAppOps(0, "pkg1")); 115 116 // multiuser & multipackage 117 mFsc.onAppOpChanged(8, 50, "pkg1", true); 118 mFsc.onAppOpChanged(1, 60, "pkg3", true); 119 mFsc.onAppOpChanged(7, 500000, "pkg2", true); 120 121 assertEquals(1, mFsc.getAppOps(0, "pkg1").size()); 122 assertTrue(mFsc.getAppOps(0, "pkg1").contains(8)); 123 124 assertEquals(1, mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size()); 125 assertTrue(mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7)); 126 127 assertEquals(1, mFsc.getAppOps(0, "pkg3").size()); 128 assertTrue(mFsc.getAppOps(0, "pkg3").contains(1)); 129 130 // multiple ops for the same package 131 mFsc.onAppOpChanged(9, 50, "pkg1", true); 132 mFsc.onAppOpChanged(5, 50, "pkg1", true); 133 134 assertEquals(3, mFsc.getAppOps(0, "pkg1").size()); 135 assertTrue(mFsc.getAppOps(0, "pkg1").contains(8)); 136 assertTrue(mFsc.getAppOps(0, "pkg1").contains(9)); 137 assertTrue(mFsc.getAppOps(0, "pkg1").contains(5)); 138 139 assertEquals(1, mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size()); 140 assertTrue(mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7)); 141 142 // remove one of the multiples 143 mFsc.onAppOpChanged(9, 50, "pkg1", false); 144 assertEquals(2, mFsc.getAppOps(0, "pkg1").size()); 145 assertTrue(mFsc.getAppOps(0, "pkg1").contains(8)); 146 assertTrue(mFsc.getAppOps(0, "pkg1").contains(5)); 147 148 // remove last op 149 mFsc.onAppOpChanged(1, 60, "pkg3", false); 150 assertNull(mFsc.getAppOps(0, "pkg3")); 151 } 152 153 @Test testDisclosurePredicate()154 public void testDisclosurePredicate() { 155 StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1", 156 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); 157 StatusBarNotification sbn_user1_disclosure = makeMockSBN(USERID_ONE, "android", 158 SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICES, 159 null, Notification.FLAG_NO_CLEAR); 160 161 assertTrue(mFsc.isDisclosureNotification(sbn_user1_disclosure)); 162 assertFalse(mFsc.isDisclosureNotification(sbn_user1_app1)); 163 } 164 165 @Test testNeedsDisclosureAfterRemovingUnrelatedNotification()166 public void testNeedsDisclosureAfterRemovingUnrelatedNotification() { 167 final String PKG1 = "com.example.app100"; 168 169 StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, PKG1, 170 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); 171 StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1); 172 173 // first add a normal notification 174 entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); 175 // nothing required yet 176 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); 177 // now the app starts a fg service 178 entryAdded(makeMockDisclosure(USERID_ONE, new String[]{PKG1}), 179 NotificationManager.IMPORTANCE_DEFAULT); 180 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! 181 // add the fg notification 182 entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); 183 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // app1 has got it covered 184 // remove the boring notification 185 entryRemoved(sbn_user1_app1); 186 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // app1 has STILL got it covered 187 entryRemoved(sbn_user1_app1_fg); 188 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! 189 } 190 191 @Test testSimpleAddRemove()192 public void testSimpleAddRemove() { 193 final String PKG1 = "com.example.app1"; 194 final String PKG2 = "com.example.app2"; 195 196 StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, PKG1, 197 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); 198 entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); 199 200 // no services are "running" 201 entryAdded(makeMockDisclosure(USERID_ONE, null), 202 NotificationManager.IMPORTANCE_DEFAULT); 203 204 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); 205 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 206 207 entryUpdated(makeMockDisclosure(USERID_ONE, new String[]{PKG1}), 208 NotificationManager.IMPORTANCE_DEFAULT); 209 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! 210 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 211 212 // switch to different package 213 entryUpdated(makeMockDisclosure(USERID_ONE, new String[]{PKG2}), 214 NotificationManager.IMPORTANCE_DEFAULT); 215 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); 216 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 217 218 entryUpdated(makeMockDisclosure(USERID_TWO, new String[]{PKG1}), 219 NotificationManager.IMPORTANCE_DEFAULT); 220 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); 221 assertTrue(mFsc.isDisclosureNeededForUser(USERID_TWO)); // finally user2 needs one too 222 223 entryUpdated(makeMockDisclosure(USERID_ONE, new String[]{PKG2, PKG1}), 224 NotificationManager.IMPORTANCE_DEFAULT); 225 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); 226 assertTrue(mFsc.isDisclosureNeededForUser(USERID_TWO)); 227 228 entryRemoved(makeMockDisclosure(USERID_ONE, null /*unused*/)); 229 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); 230 assertTrue(mFsc.isDisclosureNeededForUser(USERID_TWO)); 231 232 entryRemoved(makeMockDisclosure(USERID_TWO, null /*unused*/)); 233 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); 234 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 235 } 236 237 @Test testDisclosureBasic()238 public void testDisclosureBasic() { 239 final String PKG1 = "com.example.app0"; 240 241 StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, PKG1, 242 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); 243 StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1); 244 245 entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); // not fg 246 entryAdded(makeMockDisclosure(USERID_ONE, new String[]{PKG1}), 247 NotificationManager.IMPORTANCE_DEFAULT); 248 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! 249 entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); 250 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // app1 has got it covered 251 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 252 253 // let's take out the other notification and see what happens. 254 255 entryRemoved(sbn_user1_app1); 256 assertFalse( 257 mFsc.isDisclosureNeededForUser(USERID_ONE)); // still covered by sbn_user1_app1_fg 258 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 259 260 // let's attempt to downgrade the notification from FLAG_FOREGROUND and see what we get 261 StatusBarNotification sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1); 262 sbn_user1_app1_fg_sneaky.getNotification().flags = 0; 263 entryUpdated(sbn_user1_app1_fg_sneaky, 264 NotificationManager.IMPORTANCE_DEFAULT); 265 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! 266 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 267 268 // ok, ok, we'll put it back 269 sbn_user1_app1_fg_sneaky.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE; 270 entryUpdated(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); 271 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); 272 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 273 274 entryRemoved(sbn_user1_app1_fg_sneaky); 275 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! 276 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 277 278 // now let's test an upgrade 279 entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); 280 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); 281 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 282 sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; 283 entryUpdated(sbn_user1_app1, 284 NotificationManager.IMPORTANCE_DEFAULT); // this is now a fg notification 285 286 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 287 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); 288 289 // remove it, make sure we're out of compliance again 290 entryRemoved(sbn_user1_app1); // was fg, should return true 291 entryRemoved(sbn_user1_app1); 292 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 293 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); 294 295 // importance upgrade 296 entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN); 297 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); 298 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 299 sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; 300 entryUpdated(sbn_user1_app1_fg, 301 NotificationManager.IMPORTANCE_DEFAULT); // this is now a fg notification 302 303 // finally, let's turn off the service 304 entryAdded(makeMockDisclosure(USERID_ONE, null), 305 NotificationManager.IMPORTANCE_DEFAULT); 306 307 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); 308 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); 309 } 310 311 @Test testNoNotifsNorAppOps_noSystemAlertWarningRequired()312 public void testNoNotifsNorAppOps_noSystemAlertWarningRequired() { 313 // no notifications nor app op signals that this package/userId requires system alert 314 // warning 315 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, "any")); 316 } 317 318 @Test testCustomLayouts_systemAlertWarningRequired()319 public void testCustomLayouts_systemAlertWarningRequired() { 320 // GIVEN a notification with a custom layout 321 final String pkg = "com.example.app0"; 322 StatusBarNotification customLayoutNotif = makeMockSBN(USERID_ONE, pkg, 0, 323 false); 324 325 // WHEN the custom layout entry is added 326 entryAdded(customLayoutNotif, NotificationManager.IMPORTANCE_MIN); 327 328 // THEN a system alert warning is required since there aren't any notifications that can 329 // display the app ops 330 assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, pkg)); 331 } 332 333 @Test testStandardLayoutExists_noSystemAlertWarningRequired()334 public void testStandardLayoutExists_noSystemAlertWarningRequired() { 335 // GIVEN two notifications (one with a custom layout, the other with a standard layout) 336 final String pkg = "com.example.app0"; 337 StatusBarNotification customLayoutNotif = makeMockSBN(USERID_ONE, pkg, 0, 338 false); 339 StatusBarNotification standardLayoutNotif = makeMockSBN(USERID_ONE, pkg, 1, true); 340 341 // WHEN the entries are added 342 entryAdded(customLayoutNotif, NotificationManager.IMPORTANCE_MIN); 343 entryAdded(standardLayoutNotif, NotificationManager.IMPORTANCE_MIN); 344 345 // THEN no system alert warning is required, since there is at least one notification 346 // with a standard layout that can display the app ops on the notification 347 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, pkg)); 348 } 349 350 @Test testStandardLayoutRemoved_systemAlertWarningRequired()351 public void testStandardLayoutRemoved_systemAlertWarningRequired() { 352 // GIVEN two notifications (one with a custom layout, the other with a standard layout) 353 final String pkg = "com.example.app0"; 354 StatusBarNotification customLayoutNotif = makeMockSBN(USERID_ONE, pkg, 0, 355 false); 356 StatusBarNotification standardLayoutNotif = makeMockSBN(USERID_ONE, pkg, 1, true); 357 358 // WHEN the entries are added and then the standard layout notification is removed 359 entryAdded(customLayoutNotif, NotificationManager.IMPORTANCE_MIN); 360 entryAdded(standardLayoutNotif, NotificationManager.IMPORTANCE_MIN); 361 entryRemoved(standardLayoutNotif); 362 363 // THEN a system alert warning is required since there aren't any notifications that can 364 // display the app ops 365 assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, pkg)); 366 } 367 368 @Test testStandardLayoutUpdatedToCustomLayout_systemAlertWarningRequired()369 public void testStandardLayoutUpdatedToCustomLayout_systemAlertWarningRequired() { 370 // GIVEN a standard layout notification and then an updated version with a customLayout 371 final String pkg = "com.example.app0"; 372 StatusBarNotification standardLayoutNotif = makeMockSBN(USERID_ONE, pkg, 1, true); 373 StatusBarNotification updatedToCustomLayoutNotif = makeMockSBN(USERID_ONE, pkg, 1, false); 374 375 // WHEN the entries is added and then updated to a custom layout 376 entryAdded(standardLayoutNotif, NotificationManager.IMPORTANCE_MIN); 377 entryUpdated(updatedToCustomLayoutNotif, NotificationManager.IMPORTANCE_MIN); 378 379 // THEN a system alert warning is required since there aren't any notifications that can 380 // display the app ops 381 assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, pkg)); 382 } 383 makeMockSBN(int userId, String pkg, int id, String tag, int flags)384 private StatusBarNotification makeMockSBN(int userId, String pkg, int id, String tag, 385 int flags) { 386 final Notification n = mock(Notification.class); 387 n.extras = new Bundle(); 388 n.flags = flags; 389 return makeMockSBN(userId, pkg, id, tag, n); 390 } 391 makeMockSBN(int userid, String pkg, int id, String tag, Notification n)392 private StatusBarNotification makeMockSBN(int userid, String pkg, int id, String tag, 393 Notification n) { 394 final StatusBarNotification sbn = mock(StatusBarNotification.class); 395 when(sbn.getNotification()).thenReturn(n); 396 when(sbn.getId()).thenReturn(id); 397 when(sbn.getPackageName()).thenReturn(pkg); 398 when(sbn.getTag()).thenReturn(tag); 399 when(sbn.getUserId()).thenReturn(userid); 400 when(sbn.getUser()).thenReturn(new UserHandle(userid)); 401 when(sbn.getKey()).thenReturn("MOCK:"+userid+"|"+pkg+"|"+id+"|"+tag); 402 return sbn; 403 } 404 makeMockSBN(int uid, String pkg, int id, boolean usesStdLayout)405 private StatusBarNotification makeMockSBN(int uid, String pkg, int id, 406 boolean usesStdLayout) { 407 StatusBarNotification sbn = makeMockSBN(uid, pkg, id, "foo", 0); 408 if (usesStdLayout) { 409 sbn.getNotification().contentView = null; 410 sbn.getNotification().headsUpContentView = null; 411 sbn.getNotification().bigContentView = null; 412 } else { 413 sbn.getNotification().contentView = mock(RemoteViews.class); 414 } 415 return sbn; 416 } 417 makeMockFgSBN(int uid, String pkg, int id, boolean usesStdLayout)418 private StatusBarNotification makeMockFgSBN(int uid, String pkg, int id, 419 boolean usesStdLayout) { 420 StatusBarNotification sbn = 421 makeMockSBN(uid, pkg, id, "foo", Notification.FLAG_FOREGROUND_SERVICE); 422 if (usesStdLayout) { 423 sbn.getNotification().contentView = null; 424 sbn.getNotification().headsUpContentView = null; 425 sbn.getNotification().bigContentView = null; 426 } else { 427 sbn.getNotification().contentView = mock(RemoteViews.class); 428 } 429 return sbn; 430 } 431 makeMockFgSBN(int uid, String pkg)432 private StatusBarNotification makeMockFgSBN(int uid, String pkg) { 433 return makeMockSBN(uid, pkg, 1000, "foo", Notification.FLAG_FOREGROUND_SERVICE); 434 } 435 makeMockDisclosure(int userid, String[] pkgs)436 private StatusBarNotification makeMockDisclosure(int userid, String[] pkgs) { 437 final Notification n = mock(Notification.class); 438 n.flags = Notification.FLAG_ONGOING_EVENT; 439 final Bundle extras = new Bundle(); 440 if (pkgs != null) extras.putStringArray(Notification.EXTRA_FOREGROUND_APPS, pkgs); 441 n.extras = extras; 442 n.when = System.currentTimeMillis() - 10000; // ten seconds ago 443 final StatusBarNotification sbn = makeMockSBN(userid, "android", 444 SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICES, 445 null, n); 446 sbn.getNotification().extras = extras; 447 return sbn; 448 } 449 addFgEntry()450 private NotificationEntry addFgEntry() { 451 NotificationEntry entry = createFgEntry(); 452 mEntryListener.onPendingEntryAdded(entry); 453 return entry; 454 } 455 createFgEntry()456 private NotificationEntry createFgEntry() { 457 return new NotificationEntryBuilder() 458 .setSbn(makeMockFgSBN(0, TEST_PACKAGE_NAME, 1000, true)) 459 .setImportance(NotificationManager.IMPORTANCE_DEFAULT) 460 .build(); 461 } 462 entryRemoved(StatusBarNotification notification)463 private void entryRemoved(StatusBarNotification notification) { 464 mEntryListener.onEntryRemoved( 465 new NotificationEntryBuilder() 466 .setSbn(notification) 467 .build(), 468 null, 469 false, 470 REASON_APP_CANCEL); 471 } 472 entryAdded(StatusBarNotification notification, int importance)473 private void entryAdded(StatusBarNotification notification, int importance) { 474 NotificationEntry entry = new NotificationEntryBuilder() 475 .setSbn(notification) 476 .setImportance(importance) 477 .build(); 478 mEntryListener.onPendingEntryAdded(entry); 479 } 480 entryUpdated(StatusBarNotification notification, int importance)481 private void entryUpdated(StatusBarNotification notification, int importance) { 482 NotificationEntry entry = new NotificationEntryBuilder() 483 .setSbn(notification) 484 .setImportance(importance) 485 .build(); 486 mEntryListener.onPreEntryUpdated(entry); 487 } 488 489 @UserIdInt private static final int USERID_ONE = 10; // UserManagerService.MIN_USER_ID; 490 @UserIdInt private static final int USERID_TWO = USERID_ONE + 1; 491 private static final String TEST_PACKAGE_NAME = "test"; 492 } 493