blob: 3b6a4bde8e20dfe72b066ec3e35b7ab1d581d43b [file] [log] [blame]
Julia Reynoldsa614c272019-11-15 16:43:29 -05001/*
2 * Copyright (C) 2019 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 */
16package com.android.server.notification;
17
Julia Reynoldse43fac32019-11-20 13:36:24 -050018import static android.os.UserHandle.MIN_SECONDARY_USER_ID;
Julia Reynoldsa614c272019-11-15 16:43:29 -050019import static android.os.UserHandle.USER_SYSTEM;
20
21import static com.google.common.truth.Truth.assertThat;
22
Julia Reynoldse43fac32019-11-20 13:36:24 -050023import static org.mockito.ArgumentMatchers.any;
Julia Reynoldsa614c272019-11-15 16:43:29 -050024import static org.mockito.Mockito.mock;
25import static org.mockito.Mockito.never;
26import static org.mockito.Mockito.times;
27import static org.mockito.Mockito.verify;
28import static org.mockito.Mockito.when;
29
30import android.app.NotificationHistory;
31import android.app.NotificationHistory.HistoricalNotification;
Julia Reynoldse43fac32019-11-20 13:36:24 -050032import android.content.pm.UserInfo;
Julia Reynoldsa614c272019-11-15 16:43:29 -050033import android.graphics.drawable.Icon;
Julia Reynoldse43fac32019-11-20 13:36:24 -050034import android.os.Handler;
Julia Reynoldsa614c272019-11-15 16:43:29 -050035import android.os.UserManager;
Julia Reynoldse43fac32019-11-20 13:36:24 -050036import android.provider.Settings;
Julia Reynoldsa614c272019-11-15 16:43:29 -050037
38import androidx.test.InstrumentationRegistry;
39import androidx.test.runner.AndroidJUnit4;
40
41import com.android.server.UiServiceTestCase;
42
43import org.junit.Before;
Colin Cross5ea7fb72019-12-18 17:16:36 -080044import org.junit.Ignore;
Julia Reynoldsa614c272019-11-15 16:43:29 -050045import org.junit.Test;
46import org.junit.runner.RunWith;
47import org.mockito.Mock;
48import org.mockito.MockitoAnnotations;
49
50import java.util.ArrayList;
Julia Reynoldse43fac32019-11-20 13:36:24 -050051import java.util.List;
52
Julia Reynoldsa614c272019-11-15 16:43:29 -050053
54@RunWith(AndroidJUnit4.class)
55public class NotificationHistoryManagerTest extends UiServiceTestCase {
56
57 @Mock
Julia Reynoldsa614c272019-11-15 16:43:29 -050058 UserManager mUserManager;
59 @Mock
60 NotificationHistoryDatabase mDb;
Julia Reynoldse43fac32019-11-20 13:36:24 -050061 @Mock
62 Handler mHandler;
63 List<UserInfo> mUsers;
Julia Reynoldsa614c272019-11-15 16:43:29 -050064
65 NotificationHistoryManager mHistoryManager;
66
Julia Reynoldsa614c272019-11-15 16:43:29 -050067 private HistoricalNotification getHistoricalNotification(String packageName, int index) {
68 String expectedChannelName = "channelName" + index;
69 String expectedChannelId = "channelId" + index;
70 int expectedUid = 1123456 + index;
71 int expectedUserId = index;
72 long expectedPostTime = 987654321 + index;
73 String expectedTitle = "title" + index;
74 String expectedText = "text" + index;
75 Icon expectedIcon = Icon.createWithResource(InstrumentationRegistry.getContext(),
76 index);
77
78 return new HistoricalNotification.Builder()
79 .setPackage(packageName)
80 .setChannelName(expectedChannelName)
81 .setChannelId(expectedChannelId)
82 .setUid(expectedUid)
83 .setUserId(expectedUserId)
84 .setPostedTimeMs(expectedPostTime)
85 .setTitle(expectedTitle)
86 .setText(expectedText)
87 .setIcon(expectedIcon)
88 .build();
89 }
90
91 @Before
92 public void setUp() {
93 MockitoAnnotations.initMocks(this);
Julia Reynoldse43fac32019-11-20 13:36:24 -050094
95 getContext().addMockSystemService(UserManager.class, mUserManager);
96
97 mUsers = new ArrayList<>();
98 UserInfo userSystem = new UserInfo();
99 userSystem.id = USER_SYSTEM;
100 mUsers.add(userSystem);
101 UserInfo userAll = new UserInfo();
102 userAll.id = MIN_SECONDARY_USER_ID;
103 mUsers.add(userAll);
104 mUsers.add(userAll);
105 when(mUserManager.getUsers()).thenReturn(mUsers);
106
107 for (UserInfo info : mUsers) {
108 Settings.Secure.putIntForUser(getContext().getContentResolver(),
109 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 1, info.id);
110 }
Julia Reynoldsa614c272019-11-15 16:43:29 -0500111
112 NotificationHistoryDatabaseFactory.setTestingNotificationHistoryDatabase(mDb);
113
Julia Reynoldse43fac32019-11-20 13:36:24 -0500114 mHistoryManager = new NotificationHistoryManager(getContext(), mHandler);
115 mHistoryManager.onBootPhaseAppsCanStart();
Julia Reynoldsa614c272019-11-15 16:43:29 -0500116 }
117
118 @Test
119 public void testOnUserUnlocked() {
120 assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
121 assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse();
122 mHistoryManager.onUserUnlocked(USER_SYSTEM);
123 assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue();
124 assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isTrue();
125 verify(mDb, times(1)).init();
126 }
127
Colin Cross5ea7fb72019-12-18 17:16:36 -0800128 @Test
129 @Ignore("b/147012298")
Julia Reynoldse43fac32019-11-20 13:36:24 -0500130 public void testOnUserUnlocked_historyDisabled() {
131 Settings.Secure.putIntForUser(getContext().getContentResolver(),
132 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM);
133 mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
134 assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
135 assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse();
136
137 mHistoryManager.onUserUnlocked(USER_SYSTEM);
138
139 assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
140 assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse();
141 verify(mDb, times(1)).disableHistory();
142 }
143
Julia Reynoldsa614c272019-11-15 16:43:29 -0500144 @Test
145 public void testOnUserUnlocked_cleansUpRemovedPackages() {
146 String pkg = "pkg";
147 mHistoryManager.onPackageRemoved(USER_SYSTEM, pkg);
148 assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
149
150 mHistoryManager.onUserUnlocked(USER_SYSTEM);
151 assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue();
152 assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isTrue();
153
154 verify(mDb, times(1)).onPackageRemoved(pkg);
155 }
156
157 @Test
158 public void testOnUserStopped_userExists() {
159 mHistoryManager.onUserUnlocked(USER_SYSTEM);
160 mHistoryManager.onUserStopped(USER_SYSTEM);
161
162 assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
163 assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse();
164 }
165
166 @Test
167 public void testOnUserStopped_userDoesNotExist() {
168 mHistoryManager.onUserStopped(USER_SYSTEM);
169 // no crash
170 assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
171 assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse();
172 }
173
174 @Test
175 public void testOnUserRemoved_userExists() {
176 mHistoryManager.onUserUnlocked(USER_SYSTEM);
177 mHistoryManager.onUserRemoved(USER_SYSTEM);
178
179 assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
180 assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse();
Julia Reynoldse43fac32019-11-20 13:36:24 -0500181 assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isFalse();
Julia Reynoldsa614c272019-11-15 16:43:29 -0500182 }
183
184 @Test
185 public void testOnUserRemoved_userDoesNotExist() {
186 mHistoryManager.onUserRemoved(USER_SYSTEM);
187 // no crash
188 assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
189 assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse();
190 }
191
192 @Test
193 public void testOnUserRemoved_cleanupPendingPackages() {
194 mHistoryManager.onUserUnlocked(USER_SYSTEM);
195 mHistoryManager.onUserStopped(USER_SYSTEM);
196 String pkg = "pkg";
197 mHistoryManager.onPackageRemoved(USER_SYSTEM, pkg);
198 mHistoryManager.onUserRemoved(USER_SYSTEM);
199
200 assertThat(mHistoryManager.getPendingPackageRemovalsForUser(USER_SYSTEM)).isNull();
201 }
202
203 @Test
204 public void testOnPackageRemoved_userUnlocked() {
205 String pkg = "pkg";
206 NotificationHistoryDatabase userHistory = mock(NotificationHistoryDatabase.class);
207
208 mHistoryManager.onUserUnlocked(USER_SYSTEM);
209 mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistory);
210
211 mHistoryManager.onPackageRemoved(USER_SYSTEM, pkg);
212
213 verify(userHistory, times(1)).onPackageRemoved(pkg);
214 }
215
216 @Test
217 public void testOnPackageRemoved_userLocked() {
218 String pkg = "pkg";
219 mHistoryManager.onPackageRemoved(USER_SYSTEM, pkg);
220
221 assertThat(mHistoryManager.getPendingPackageRemovalsForUser(USER_SYSTEM)).contains(pkg);
222 }
223
224 @Test
Julia Reynoldse43fac32019-11-20 13:36:24 -0500225 public void testOnPackageRemoved_historyDisabled() {
226 Settings.Secure.putIntForUser(getContext().getContentResolver(),
227 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM);
228 mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
229 String pkg = "pkg";
230 mHistoryManager.onPackageRemoved(USER_SYSTEM, pkg);
231
232 assertThat(mHistoryManager.getPendingPackageRemovalsForUser(USER_SYSTEM))
233 .isNull();
234 }
235
236 @Test
Julia Reynoldsa614c272019-11-15 16:43:29 -0500237 public void testOnPackageRemoved_multiUser() {
238 String pkg = "pkg";
239 NotificationHistoryDatabase userHistorySystem = mock(NotificationHistoryDatabase.class);
240 NotificationHistoryDatabase userHistoryAll = mock(NotificationHistoryDatabase.class);
241
242 mHistoryManager.onUserUnlocked(USER_SYSTEM);
243 mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem);
244
Julia Reynoldse43fac32019-11-20 13:36:24 -0500245 mHistoryManager.onUserUnlocked(MIN_SECONDARY_USER_ID);
246 mHistoryManager.replaceNotificationHistoryDatabase(MIN_SECONDARY_USER_ID, userHistoryAll);
Julia Reynoldsa614c272019-11-15 16:43:29 -0500247
248 mHistoryManager.onPackageRemoved(USER_SYSTEM, pkg);
249
250 verify(userHistorySystem, times(1)).onPackageRemoved(pkg);
251 verify(userHistoryAll, never()).onPackageRemoved(pkg);
252 }
253
254 @Test
255 public void testTriggerWriteToDisk() {
256 NotificationHistoryDatabase userHistorySystem = mock(NotificationHistoryDatabase.class);
257 NotificationHistoryDatabase userHistoryAll = mock(NotificationHistoryDatabase.class);
258
259 mHistoryManager.onUserUnlocked(USER_SYSTEM);
260 mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem);
261
Julia Reynoldse43fac32019-11-20 13:36:24 -0500262 mHistoryManager.onUserUnlocked(MIN_SECONDARY_USER_ID);
263 mHistoryManager.replaceNotificationHistoryDatabase(MIN_SECONDARY_USER_ID, userHistoryAll);
Julia Reynoldsa614c272019-11-15 16:43:29 -0500264
265 mHistoryManager.triggerWriteToDisk();
266
267 verify(userHistorySystem, times(1)).forceWriteToDisk();
268 verify(userHistoryAll, times(1)).forceWriteToDisk();
269 }
270
271 @Test
272 public void testTriggerWriteToDisk_onlyUnlockedUsers() {
273 NotificationHistoryDatabase userHistorySystem = mock(NotificationHistoryDatabase.class);
274 NotificationHistoryDatabase userHistoryAll = mock(NotificationHistoryDatabase.class);
275
276 mHistoryManager.onUserUnlocked(USER_SYSTEM);
277 mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem);
278
Julia Reynoldse43fac32019-11-20 13:36:24 -0500279 mHistoryManager.onUserUnlocked(MIN_SECONDARY_USER_ID);
280 mHistoryManager.replaceNotificationHistoryDatabase(MIN_SECONDARY_USER_ID, userHistoryAll);
281 mHistoryManager.onUserStopped(MIN_SECONDARY_USER_ID);
Julia Reynoldsa614c272019-11-15 16:43:29 -0500282
283 mHistoryManager.triggerWriteToDisk();
284
285 verify(userHistorySystem, times(1)).forceWriteToDisk();
286 verify(userHistoryAll, never()).forceWriteToDisk();
287 }
288
289 @Test
Julia Reynoldse43fac32019-11-20 13:36:24 -0500290 public void testTriggerWriteToDisk_historyDisabled() {
291 Settings.Secure.putIntForUser(getContext().getContentResolver(),
292 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM);
293 mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
294 NotificationHistoryDatabase userHistorySystem = mock(NotificationHistoryDatabase.class);
295
296 mHistoryManager.onUserUnlocked(USER_SYSTEM);
297 mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem);
298
299 mHistoryManager.triggerWriteToDisk();
300
301 verify(userHistorySystem, never()).forceWriteToDisk();
302 }
303
304 @Test
Julia Reynoldsa614c272019-11-15 16:43:29 -0500305 public void testAddNotification_userLocked_noCrash() {
306 HistoricalNotification hn = getHistoricalNotification("pkg", 1);
307
308 mHistoryManager.addNotification(hn);
309 }
310
311 @Test
Julia Reynoldse43fac32019-11-20 13:36:24 -0500312 public void testAddNotification_historyDisabled() {
313 HistoricalNotification hn = getHistoricalNotification("pkg", 1);
314
315 Settings.Secure.putIntForUser(getContext().getContentResolver(),
316 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, hn.getUserId());
317 mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
318
319 mHistoryManager.onUserUnlocked(hn.getUserId());
320 mHistoryManager.addNotification(hn);
321
322 verify(mDb, never()).addNotification(any());
323 }
324
325 @Test
Julia Reynoldsa614c272019-11-15 16:43:29 -0500326 public void testAddNotification() {
327 HistoricalNotification hnSystem = getHistoricalNotification("pkg", USER_SYSTEM);
Julia Reynoldse43fac32019-11-20 13:36:24 -0500328 HistoricalNotification hnAll = getHistoricalNotification("pkg", MIN_SECONDARY_USER_ID);
Julia Reynoldsa614c272019-11-15 16:43:29 -0500329
330 NotificationHistoryDatabase userHistorySystem = mock(NotificationHistoryDatabase.class);
331 NotificationHistoryDatabase userHistoryAll = mock(NotificationHistoryDatabase.class);
332
333 mHistoryManager.onUserUnlocked(USER_SYSTEM);
334 mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem);
335
Julia Reynoldse43fac32019-11-20 13:36:24 -0500336 mHistoryManager.onUserUnlocked(MIN_SECONDARY_USER_ID);
337 mHistoryManager.replaceNotificationHistoryDatabase(MIN_SECONDARY_USER_ID, userHistoryAll);
Julia Reynoldsa614c272019-11-15 16:43:29 -0500338
339 mHistoryManager.addNotification(hnSystem);
340 mHistoryManager.addNotification(hnAll);
341
342 verify(userHistorySystem, times(1)).addNotification(hnSystem);
343 verify(userHistoryAll, times(1)).addNotification(hnAll);
344 }
345
346 @Test
347 public void testReadNotificationHistory() {
348 HistoricalNotification hnSystem = getHistoricalNotification("pkg", USER_SYSTEM);
Julia Reynoldse43fac32019-11-20 13:36:24 -0500349 HistoricalNotification hnAll = getHistoricalNotification("pkg", MIN_SECONDARY_USER_ID);
Julia Reynoldsa614c272019-11-15 16:43:29 -0500350
351 NotificationHistoryDatabase userHistorySystem = mock(NotificationHistoryDatabase.class);
352 NotificationHistoryDatabase userHistoryAll = mock(NotificationHistoryDatabase.class);
353
354 mHistoryManager.onUserUnlocked(USER_SYSTEM);
355 mHistoryManager.replaceNotificationHistoryDatabase(USER_SYSTEM, userHistorySystem);
356 NotificationHistory nhSystem = mock(NotificationHistory.class);
357 ArrayList<HistoricalNotification> nhSystemList = new ArrayList<>();
358 nhSystemList.add(hnSystem);
359 when(nhSystem.getNotificationsToWrite()).thenReturn(nhSystemList);
360 when(userHistorySystem.readNotificationHistory()).thenReturn(nhSystem);
361
Julia Reynoldse43fac32019-11-20 13:36:24 -0500362 mHistoryManager.onUserUnlocked(MIN_SECONDARY_USER_ID);
363 mHistoryManager.replaceNotificationHistoryDatabase(MIN_SECONDARY_USER_ID, userHistoryAll);
Julia Reynoldsa614c272019-11-15 16:43:29 -0500364 NotificationHistory nhAll = mock(NotificationHistory.class);
365 ArrayList<HistoricalNotification> nhAllList = new ArrayList<>();
366 nhAllList.add(hnAll);
367 when(nhAll.getNotificationsToWrite()).thenReturn(nhAllList);
368 when(userHistoryAll.readNotificationHistory()).thenReturn(nhAll);
369
370 // ensure read history returns both historical notifs
371 NotificationHistory nh = mHistoryManager.readNotificationHistory(
Julia Reynoldse43fac32019-11-20 13:36:24 -0500372 new int[] {USER_SYSTEM, MIN_SECONDARY_USER_ID});
Julia Reynoldsa614c272019-11-15 16:43:29 -0500373 assertThat(nh.getNotificationsToWrite()).contains(hnSystem);
374 assertThat(nh.getNotificationsToWrite()).contains(hnAll);
375 }
376
377 @Test
Julia Reynoldse43fac32019-11-20 13:36:24 -0500378 public void testReadNotificationHistory_historyDisabled() {
379 HistoricalNotification hnSystem = getHistoricalNotification("pkg", USER_SYSTEM);
380
381 mHistoryManager.onUserUnlocked(USER_SYSTEM);
382 NotificationHistory nhSystem = mock(NotificationHistory.class);
383 ArrayList<HistoricalNotification> nhSystemList = new ArrayList<>();
384 nhSystemList.add(hnSystem);
385 when(nhSystem.getNotificationsToWrite()).thenReturn(nhSystemList);
386 when(mDb.readNotificationHistory()).thenReturn(nhSystem);
387
388 mHistoryManager.onUserUnlocked(USER_SYSTEM);
389
390 Settings.Secure.putIntForUser(getContext().getContentResolver(),
391 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM);
392 mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
393
394 NotificationHistory nh =
395 mHistoryManager.readNotificationHistory(new int[] {USER_SYSTEM,});
396 assertThat(nh.getNotificationsToWrite()).isEmpty();
397 }
398
399 @Test
400 public void testReadFilteredNotificationHistory_userLocked() {
401 NotificationHistory nh =
402 mHistoryManager.readFilteredNotificationHistory(USER_SYSTEM, "", "", 1000);
403 assertThat(nh.getNotificationsToWrite()).isEmpty();
404 }
405
406 @Test
407 public void testReadFilteredNotificationHistory_historyDisabled() {
408 Settings.Secure.putIntForUser(getContext().getContentResolver(),
409 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM);
410 mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
411
412 mHistoryManager.onUserUnlocked(USER_SYSTEM);
Julia Reynoldsa614c272019-11-15 16:43:29 -0500413 NotificationHistory nh =
414 mHistoryManager.readFilteredNotificationHistory(USER_SYSTEM, "", "", 1000);
415 assertThat(nh.getNotificationsToWrite()).isEmpty();
416 }
417
418 @Test
419 public void readFilteredNotificationHistory() {
420 mHistoryManager.onUserUnlocked(USER_SYSTEM);
421
422 mHistoryManager.readFilteredNotificationHistory(USER_SYSTEM, "pkg", "chn", 1000);
423 verify(mDb, times(1)).readNotificationHistory("pkg", "chn", 1000);
424 }
Julia Reynoldse43fac32019-11-20 13:36:24 -0500425
426 @Test
427 public void testIsHistoryEnabled() {
428 assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isTrue();
429
430 Settings.Secure.putIntForUser(getContext().getContentResolver(),
431 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM);
432 mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
433
434 assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isFalse();
435 }
Julia Reynoldsa614c272019-11-15 16:43:29 -0500436}