blob: 31e8071f56774e48da426a90a2753cee64472bfc [file] [log] [blame]
Dan Sandlerf5aafb92017-05-28 12:18:53 -04001/*
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
17package com.android.systemui;
18
Julia Reynoldsfc640012018-02-21 12:25:27 -050019import static junit.framework.Assert.assertEquals;
20import static junit.framework.Assert.assertNull;
21
22import static org.junit.Assert.assertFalse;
23import static org.junit.Assert.assertTrue;
24import static org.mockito.Mockito.mock;
Gus Prevaseb4e2e12018-12-28 14:57:59 -050025import static org.mockito.Mockito.verify;
Julia Reynoldsfc640012018-02-21 12:25:27 -050026import static org.mockito.Mockito.when;
27
Dan Sandlerf5aafb92017-05-28 12:18:53 -040028import android.annotation.UserIdInt;
29import android.app.Notification;
30import android.app.NotificationManager;
31import android.os.Bundle;
32import android.os.UserHandle;
33import android.service.notification.StatusBarNotification;
34import android.support.test.filters.SmallTest;
35import android.support.test.runner.AndroidJUnit4;
Julia Reynoldsfc640012018-02-21 12:25:27 -050036import android.widget.RemoteViews;
37
Dan Sandlerf5aafb92017-05-28 12:18:53 -040038import com.android.internal.messages.nano.SystemMessageProto;
Gus Prevaseb4e2e12018-12-28 14:57:59 -050039import com.android.systemui.statusbar.notification.NotificationEntryListener;
40import com.android.systemui.statusbar.notification.NotificationEntryManager;
Ned Burnsf81c4c42019-01-07 14:10:43 -050041import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Dan Sandlerf5aafb92017-05-28 12:18:53 -040042
43import org.junit.Before;
44import org.junit.Test;
45import org.junit.runner.RunWith;
Gus Prevaseb4e2e12018-12-28 14:57:59 -050046import org.mockito.ArgumentCaptor;
Dan Sandlerf5aafb92017-05-28 12:18:53 -040047
Dan Sandlerf5aafb92017-05-28 12:18:53 -040048@SmallTest
49@RunWith(AndroidJUnit4.class)
50public class ForegroundServiceControllerTest extends SysuiTestCase {
Gus Prevaseb4e2e12018-12-28 14:57:59 -050051 @UserIdInt private static final int USERID_ONE = 10; // UserManagerService.MIN_USER_ID;
52 @UserIdInt private static final int USERID_TWO = USERID_ONE + 1;
Dan Sandlerf5aafb92017-05-28 12:18:53 -040053
Gus Prevaseb4e2e12018-12-28 14:57:59 -050054 private ForegroundServiceController mFsc;
55 private ForegroundServiceNotificationListener mListener;
56 private NotificationEntryListener mEntryListener;
Dan Sandlerf5aafb92017-05-28 12:18:53 -040057
58 @Before
59 public void setUp() throws Exception {
Gus Prevaseb4e2e12018-12-28 14:57:59 -050060 mFsc = new ForegroundServiceController();
61 NotificationEntryManager notificationEntryManager = mock(NotificationEntryManager.class);
62 mListener = new ForegroundServiceNotificationListener(
63 mContext, mFsc, notificationEntryManager);
64 ArgumentCaptor<NotificationEntryListener> entryListenerCaptor =
65 ArgumentCaptor.forClass(NotificationEntryListener.class);
66 verify(notificationEntryManager).addNotificationEntryListener(
67 entryListenerCaptor.capture());
68 mEntryListener = entryListenerCaptor.getValue();
Julia Reynoldsfc640012018-02-21 12:25:27 -050069 }
70
71 @Test
72 public void testAppOpsCRUD() {
73 // no crash on remove that doesn't exist
Gus Prevaseb4e2e12018-12-28 14:57:59 -050074 mFsc.onAppOpChanged(9, 1000, "pkg1", false);
75 assertNull(mFsc.getAppOps(0, "pkg1"));
Julia Reynoldsfc640012018-02-21 12:25:27 -050076
77 // multiuser & multipackage
Gus Prevaseb4e2e12018-12-28 14:57:59 -050078 mFsc.onAppOpChanged(8, 50, "pkg1", true);
79 mFsc.onAppOpChanged(1, 60, "pkg3", true);
80 mFsc.onAppOpChanged(7, 500000, "pkg2", true);
Julia Reynoldsfc640012018-02-21 12:25:27 -050081
Gus Prevaseb4e2e12018-12-28 14:57:59 -050082 assertEquals(1, mFsc.getAppOps(0, "pkg1").size());
83 assertTrue(mFsc.getAppOps(0, "pkg1").contains(8));
Julia Reynoldsfc640012018-02-21 12:25:27 -050084
Gus Prevaseb4e2e12018-12-28 14:57:59 -050085 assertEquals(1, mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size());
86 assertTrue(mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7));
Julia Reynoldsfc640012018-02-21 12:25:27 -050087
Gus Prevaseb4e2e12018-12-28 14:57:59 -050088 assertEquals(1, mFsc.getAppOps(0, "pkg3").size());
89 assertTrue(mFsc.getAppOps(0, "pkg3").contains(1));
Julia Reynoldsfc640012018-02-21 12:25:27 -050090
91 // multiple ops for the same package
Gus Prevaseb4e2e12018-12-28 14:57:59 -050092 mFsc.onAppOpChanged(9, 50, "pkg1", true);
93 mFsc.onAppOpChanged(5, 50, "pkg1", true);
Julia Reynoldsfc640012018-02-21 12:25:27 -050094
Gus Prevaseb4e2e12018-12-28 14:57:59 -050095 assertEquals(3, mFsc.getAppOps(0, "pkg1").size());
96 assertTrue(mFsc.getAppOps(0, "pkg1").contains(8));
97 assertTrue(mFsc.getAppOps(0, "pkg1").contains(9));
98 assertTrue(mFsc.getAppOps(0, "pkg1").contains(5));
Julia Reynoldsfc640012018-02-21 12:25:27 -050099
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500100 assertEquals(1, mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size());
101 assertTrue(mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500102
103 // remove one of the multiples
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500104 mFsc.onAppOpChanged(9, 50, "pkg1", false);
105 assertEquals(2, mFsc.getAppOps(0, "pkg1").size());
106 assertTrue(mFsc.getAppOps(0, "pkg1").contains(8));
107 assertTrue(mFsc.getAppOps(0, "pkg1").contains(5));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500108
109 // remove last op
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500110 mFsc.onAppOpChanged(1, 60, "pkg3", false);
111 assertNull(mFsc.getAppOps(0, "pkg3"));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500112 }
113
114 @Test
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500115 public void testDisclosurePredicate() {
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400116 StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1",
117 5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500118 StatusBarNotification sbn_user1_disclosure = makeMockSBN(USERID_ONE, "android",
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400119 SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICES,
120 null, Notification.FLAG_NO_CLEAR);
121
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500122 assertTrue(mFsc.isDisclosureNotification(sbn_user1_disclosure));
123 assertFalse(mFsc.isDisclosureNotification(sbn_user1_app1));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400124 }
125
126 @Test
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500127 public void testNeedsDisclosureAfterRemovingUnrelatedNotification() {
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400128 final String PKG1 = "com.example.app100";
129
130 StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, PKG1,
131 5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
132 StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1);
133
134 // first add a normal notification
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500135 entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT);
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400136 // nothing required yet
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500137 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400138 // now the app starts a fg service
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500139 entryAdded(makeMockDisclosure(USERID_ONE, new String[]{PKG1}),
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400140 NotificationManager.IMPORTANCE_DEFAULT);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500141 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required!
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400142 // add the fg notification
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500143 entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT);
144 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // app1 has got it covered
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400145 // remove the boring notification
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500146 entryRemoved(sbn_user1_app1);
147 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // app1 has STILL got it covered
148 entryRemoved(sbn_user1_app1_fg);
149 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required!
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400150 }
151
152 @Test
153 public void testSimpleAddRemove() {
154 final String PKG1 = "com.example.app1";
155 final String PKG2 = "com.example.app2";
156
157 StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, PKG1,
158 5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500159 entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT);
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400160
161 // no services are "running"
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500162 entryAdded(makeMockDisclosure(USERID_ONE, null),
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400163 NotificationManager.IMPORTANCE_DEFAULT);
164
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500165 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE));
166 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400167
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500168 entryUpdated(makeMockDisclosure(USERID_ONE, new String[]{PKG1}),
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400169 NotificationManager.IMPORTANCE_DEFAULT);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500170 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required!
171 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400172
173 // switch to different package
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500174 entryUpdated(makeMockDisclosure(USERID_ONE, new String[]{PKG2}),
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400175 NotificationManager.IMPORTANCE_DEFAULT);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500176 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE));
177 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400178
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500179 entryUpdated(makeMockDisclosure(USERID_TWO, new String[]{PKG1}),
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400180 NotificationManager.IMPORTANCE_DEFAULT);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500181 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE));
182 assertTrue(mFsc.isDisclosureNeededForUser(USERID_TWO)); // finally user2 needs one too
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400183
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500184 entryUpdated(makeMockDisclosure(USERID_ONE, new String[]{PKG2, PKG1}),
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400185 NotificationManager.IMPORTANCE_DEFAULT);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500186 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE));
187 assertTrue(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400188
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500189 entryRemoved(makeMockDisclosure(USERID_ONE, null /*unused*/));
190 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE));
191 assertTrue(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400192
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500193 entryRemoved(makeMockDisclosure(USERID_TWO, null /*unused*/));
194 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE));
195 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400196 }
197
198 @Test
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500199 public void testDisclosureBasic() {
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400200 final String PKG1 = "com.example.app0";
201
202 StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, PKG1,
203 5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
204 StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1);
205
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500206 entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); // not fg
207 entryAdded(makeMockDisclosure(USERID_ONE, new String[]{PKG1}),
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400208 NotificationManager.IMPORTANCE_DEFAULT);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500209 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required!
210 entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT);
211 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // app1 has got it covered
212 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400213
214 // let's take out the other notification and see what happens.
215
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500216 entryRemoved(sbn_user1_app1);
217 assertFalse(
218 mFsc.isDisclosureNeededForUser(USERID_ONE)); // still covered by sbn_user1_app1_fg
219 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400220
221 // let's attempt to downgrade the notification from FLAG_FOREGROUND and see what we get
222 StatusBarNotification sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1);
223 sbn_user1_app1_fg_sneaky.getNotification().flags = 0;
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500224 entryUpdated(sbn_user1_app1_fg_sneaky,
225 NotificationManager.IMPORTANCE_DEFAULT);
226 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required!
227 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400228
229 // ok, ok, we'll put it back
230 sbn_user1_app1_fg_sneaky.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500231 entryUpdated(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT);
232 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE));
233 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400234
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500235 entryRemoved(sbn_user1_app1_fg_sneaky);
236 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required!
237 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400238
239 // now let's test an upgrade
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500240 entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT);
241 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE));
242 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400243 sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500244 entryUpdated(sbn_user1_app1,
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400245 NotificationManager.IMPORTANCE_DEFAULT); // this is now a fg notification
246
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500247 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
248 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400249
250 // remove it, make sure we're out of compliance again
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500251 entryRemoved(sbn_user1_app1); // was fg, should return true
252 entryRemoved(sbn_user1_app1);
253 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
254 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400255
Julia Reynoldsfc640012018-02-21 12:25:27 -0500256 // importance upgrade
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500257 entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
258 assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE));
259 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500260 sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500261 entryUpdated(sbn_user1_app1_fg,
Julia Reynoldsfc640012018-02-21 12:25:27 -0500262 NotificationManager.IMPORTANCE_DEFAULT); // this is now a fg notification
263
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400264 // finally, let's turn off the service
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500265 entryAdded(makeMockDisclosure(USERID_ONE, null),
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400266 NotificationManager.IMPORTANCE_DEFAULT);
267
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500268 assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE));
269 assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO));
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400270 }
271
Julia Reynoldsfc640012018-02-21 12:25:27 -0500272 @Test
Julia Reynoldsaf78a792018-03-06 14:27:00 -0500273 public void testOverlayPredicate() {
274 StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1",
275 5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
276 StatusBarNotification sbn_user1_overlay = makeMockSBN(USERID_ONE, "android",
277 0, "AlertWindowNotification", Notification.FLAG_NO_CLEAR);
278
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500279 assertTrue(mFsc.isSystemAlertNotification(sbn_user1_overlay));
280 assertFalse(mFsc.isSystemAlertNotification(sbn_user1_app1));
Julia Reynoldsaf78a792018-03-06 14:27:00 -0500281 }
282
283 @Test
Julia Reynoldsfc640012018-02-21 12:25:27 -0500284 public void testStdLayoutBasic() {
285 final String PKG1 = "com.example.app0";
286
287 StatusBarNotification sbn_user1_app1 = makeMockFgSBN(USERID_ONE, PKG1, 0, true);
288 sbn_user1_app1.getNotification().flags = 0;
289 StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1, 1, true);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500290 entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); // not fg
291 assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
292 entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
293 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // app1 has got it covered
294 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "otherpkg"));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500295 // let's take out the non-fg notification and see what happens.
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500296 entryRemoved(sbn_user1_app1);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500297 // still covered by sbn_user1_app1_fg
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500298 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
299 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "anyPkg"));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500300
301 // let's attempt to downgrade the notification from FLAG_FOREGROUND and see what we get
302 StatusBarNotification sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1, 1, true);
303 sbn_user1_app1_fg_sneaky.getNotification().flags = 0;
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500304 entryUpdated(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN);
305 assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
306 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "anything"));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500307 // ok, ok, we'll put it back
308 sbn_user1_app1_fg_sneaky.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500309 entryUpdated(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
310 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
311 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "whatever"));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500312
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500313 entryRemoved(sbn_user1_app1_fg_sneaky);
314 assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
315 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "a"));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500316
317 // let's try a custom layout
318 sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1, 1, false);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500319 entryUpdated(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN);
320 assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
321 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "anything"));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500322 // now let's test an upgrade (non fg to fg)
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500323 entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN);
324 assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
325 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "b"));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500326 sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500327 entryUpdated(sbn_user1_app1,
Julia Reynoldsfc640012018-02-21 12:25:27 -0500328 NotificationManager.IMPORTANCE_MIN); // this is now a fg notification
329
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500330 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1));
331 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500332
333 // remove it, make sure we're out of compliance again
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500334 entryRemoved(sbn_user1_app1); // was fg, should return true
335 entryRemoved(sbn_user1_app1);
336 assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1));
337 assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500338 }
339
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400340 private StatusBarNotification makeMockSBN(int userid, String pkg, int id, String tag,
341 int flags) {
342 final Notification n = mock(Notification.class);
Julia Reynoldsfc640012018-02-21 12:25:27 -0500343 n.extras = new Bundle();
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400344 n.flags = flags;
345 return makeMockSBN(userid, pkg, id, tag, n);
346 }
Julia Reynoldsfc640012018-02-21 12:25:27 -0500347
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400348 private StatusBarNotification makeMockSBN(int userid, String pkg, int id, String tag,
349 Notification n) {
350 final StatusBarNotification sbn = mock(StatusBarNotification.class);
351 when(sbn.getNotification()).thenReturn(n);
352 when(sbn.getId()).thenReturn(id);
353 when(sbn.getPackageName()).thenReturn(pkg);
Julia Reynoldsaf78a792018-03-06 14:27:00 -0500354 when(sbn.getTag()).thenReturn(tag);
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400355 when(sbn.getUserId()).thenReturn(userid);
356 when(sbn.getUser()).thenReturn(new UserHandle(userid));
357 when(sbn.getKey()).thenReturn("MOCK:"+userid+"|"+pkg+"|"+id+"|"+tag);
358 return sbn;
359 }
Julia Reynoldsfc640012018-02-21 12:25:27 -0500360
361 private StatusBarNotification makeMockFgSBN(int userid, String pkg, int id,
362 boolean usesStdLayout) {
363 StatusBarNotification sbn =
364 makeMockSBN(userid, pkg, id, "foo", Notification.FLAG_FOREGROUND_SERVICE);
365 if (usesStdLayout) {
366 sbn.getNotification().contentView = null;
367 sbn.getNotification().headsUpContentView = null;
368 sbn.getNotification().bigContentView = null;
369 } else {
370 sbn.getNotification().contentView = mock(RemoteViews.class);
371 }
372 return sbn;
373 }
374
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400375 private StatusBarNotification makeMockFgSBN(int userid, String pkg) {
376 return makeMockSBN(userid, pkg, 1000, "foo", Notification.FLAG_FOREGROUND_SERVICE);
377 }
Julia Reynoldsfc640012018-02-21 12:25:27 -0500378
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500379 private StatusBarNotification makeMockDisclosure(int userid, String[] pkgs) {
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400380 final Notification n = mock(Notification.class);
381 n.flags = Notification.FLAG_ONGOING_EVENT;
382 final Bundle extras = new Bundle();
383 if (pkgs != null) extras.putStringArray(Notification.EXTRA_FOREGROUND_APPS, pkgs);
384 n.extras = extras;
Dan Sandler9830b5a2017-10-26 23:27:57 -0400385 n.when = System.currentTimeMillis() - 10000; // ten seconds ago
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400386 final StatusBarNotification sbn = makeMockSBN(userid, "android",
387 SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICES,
388 null, n);
389 sbn.getNotification().extras = extras;
390 return sbn;
391 }
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500392
393 private void entryRemoved(StatusBarNotification notification) {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500394 mEntryListener.onEntryRemoved(new NotificationEntry(notification),
Ned Burnsef2ef6c2019-01-02 16:48:08 -0500395 null, false);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500396 }
397
398 private void entryAdded(StatusBarNotification notification, int importance) {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500399 NotificationEntry entry = new NotificationEntry(notification);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500400 entry.importance = importance;
401 mEntryListener.onPendingEntryAdded(entry);
402 }
403
404 private void entryUpdated(StatusBarNotification notification, int importance) {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500405 NotificationEntry entry = new NotificationEntry(notification);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500406 entry.importance = importance;
Mady Mellor0ad5b9d2019-01-08 14:59:55 -0800407 mEntryListener.onPostEntryUpdated(entry);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500408 }
Dan Sandlerf5aafb92017-05-28 12:18:53 -0400409}