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