1 /* 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 */ 16 17 package android.app; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import android.app.NotificationHistory.HistoricalNotification; 22 import android.graphics.drawable.Icon; 23 import android.os.Parcel; 24 25 import androidx.test.InstrumentationRegistry; 26 import androidx.test.runner.AndroidJUnit4; 27 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 31 import java.util.ArrayList; 32 import java.util.Arrays; 33 import java.util.HashSet; 34 import java.util.List; 35 import java.util.Set; 36 37 @RunWith(AndroidJUnit4.class) 38 public class NotificationHistoryTest { 39 getHistoricalNotification(int index)40 private HistoricalNotification getHistoricalNotification(int index) { 41 return getHistoricalNotification("package" + index, index); 42 } 43 getHistoricalNotification(String packageName, int index)44 private HistoricalNotification getHistoricalNotification(String packageName, int index) { 45 String expectedChannelName = "channelName" + index; 46 String expectedChannelId = "channelId" + index; 47 int expectedUid = 1123456 + index; 48 int expectedUserId = 11 + index; 49 long expectedPostTime = 987654321 + index; 50 String expectedTitle = "title" + index; 51 String expectedText = "text" + index; 52 Icon expectedIcon = Icon.createWithResource(InstrumentationRegistry.getContext(), 53 index); 54 String conversationId = null; 55 if (index % 2 == 0) { 56 conversationId = "convo" + index; 57 } 58 59 return new HistoricalNotification.Builder() 60 .setPackage(packageName) 61 .setChannelName(expectedChannelName) 62 .setChannelId(expectedChannelId) 63 .setUid(expectedUid) 64 .setUserId(expectedUserId) 65 .setPostedTimeMs(expectedPostTime) 66 .setTitle(expectedTitle) 67 .setText(expectedText) 68 .setIcon(expectedIcon) 69 .setConversationId(conversationId) 70 .build(); 71 } 72 73 @Test testHistoricalNotificationBuilder()74 public void testHistoricalNotificationBuilder() { 75 String expectedPackage = "package"; 76 String expectedChannelName = "channelName"; 77 String expectedChannelId = "channelId"; 78 int expectedUid = 1123456; 79 int expectedUserId = 11; 80 long expectedPostTime = 987654321; 81 String expectedTitle = "title"; 82 String expectedText = "text"; 83 Icon expectedIcon = Icon.createWithResource(InstrumentationRegistry.getContext(), 84 android.R.drawable.btn_star); 85 String expectedConversationId = "convo"; 86 87 HistoricalNotification n = new HistoricalNotification.Builder() 88 .setPackage(expectedPackage) 89 .setChannelName(expectedChannelName) 90 .setChannelId(expectedChannelId) 91 .setUid(expectedUid) 92 .setUserId(expectedUserId) 93 .setPostedTimeMs(expectedPostTime) 94 .setTitle(expectedTitle) 95 .setText(expectedText) 96 .setIcon(expectedIcon) 97 .setConversationId(expectedConversationId) 98 .build(); 99 100 assertThat(n.getPackage()).isEqualTo(expectedPackage); 101 assertThat(n.getChannelName()).isEqualTo(expectedChannelName); 102 assertThat(n.getChannelId()).isEqualTo(expectedChannelId); 103 assertThat(n.getUid()).isEqualTo(expectedUid); 104 assertThat(n.getUserId()).isEqualTo(expectedUserId); 105 assertThat(n.getPostedTimeMs()).isEqualTo(expectedPostTime); 106 assertThat(n.getTitle()).isEqualTo(expectedTitle); 107 assertThat(n.getText()).isEqualTo(expectedText); 108 assertThat(expectedIcon.sameAs(n.getIcon())).isTrue(); 109 assertThat(n.getConversationId()).isEqualTo(expectedConversationId); 110 } 111 112 @Test testAddNotificationToWrite()113 public void testAddNotificationToWrite() { 114 NotificationHistory history = new NotificationHistory(); 115 HistoricalNotification n = getHistoricalNotification(0); 116 HistoricalNotification n2 = getHistoricalNotification(1); 117 118 history.addNotificationToWrite(n2); 119 history.addNotificationToWrite(n); 120 121 assertThat(history.getNotificationsToWrite().size()).isEqualTo(2); 122 assertThat(history.getNotificationsToWrite().get(0)).isSameInstanceAs(n2); 123 assertThat(history.getNotificationsToWrite().get(1)).isSameInstanceAs(n); 124 assertThat(history.getHistoryCount()).isEqualTo(2); 125 } 126 127 @Test testAddNotificationsToWrite()128 public void testAddNotificationsToWrite() { 129 NotificationHistory history = new NotificationHistory(); 130 HistoricalNotification n = getHistoricalNotification(3); 131 HistoricalNotification n2 = getHistoricalNotification(1); 132 HistoricalNotification n5 = getHistoricalNotification(0); 133 history.addNotificationToWrite(n2); 134 history.addNotificationToWrite(n); 135 history.addNotificationToWrite(n5); 136 137 NotificationHistory secondHistory = new NotificationHistory(); 138 HistoricalNotification n3 = getHistoricalNotification(4); 139 HistoricalNotification n4 = getHistoricalNotification(2); 140 secondHistory.addNotificationToWrite(n4); 141 secondHistory.addNotificationToWrite(n3); 142 143 history.addNotificationsToWrite(secondHistory); 144 145 assertThat(history.getNotificationsToWrite().size()).isEqualTo(5); 146 assertThat(history.getNotificationsToWrite().get(0)).isSameInstanceAs(n3); 147 assertThat(history.getNotificationsToWrite().get(1)).isSameInstanceAs(n); 148 assertThat(history.getNotificationsToWrite().get(2)).isSameInstanceAs(n4); 149 assertThat(history.getNotificationsToWrite().get(3)).isSameInstanceAs(n2); 150 assertThat(history.getNotificationsToWrite().get(4)).isSameInstanceAs(n5); 151 assertThat(history.getHistoryCount()).isEqualTo(5); 152 153 assertThat(history.getPooledStringsToWrite()).asList().contains(n2.getChannelName()); 154 assertThat(history.getPooledStringsToWrite()).asList().contains(n4.getPackage()); 155 } 156 157 @Test testPoolStringsFromNotifications()158 public void testPoolStringsFromNotifications() { 159 NotificationHistory history = new NotificationHistory(); 160 161 List<String> expectedStrings = new ArrayList<>(); 162 for (int i = 1; i <= 10; i++) { 163 HistoricalNotification n = getHistoricalNotification(i); 164 expectedStrings.add(n.getPackage()); 165 expectedStrings.add(n.getChannelName()); 166 expectedStrings.add(n.getChannelId()); 167 if (n.getConversationId() != null) { 168 expectedStrings.add(n.getConversationId()); 169 } 170 history.addNotificationToWrite(n); 171 } 172 173 history.poolStringsFromNotifications(); 174 175 assertThat(history.getPooledStringsToWrite().length).isEqualTo(expectedStrings.size()); 176 String previous = null; 177 for (String actual : history.getPooledStringsToWrite()) { 178 assertThat(expectedStrings).contains(actual); 179 180 if (previous != null) { 181 assertThat(actual).isGreaterThan(previous); 182 } 183 previous = actual; 184 } 185 } 186 187 @Test testAddPooledStrings()188 public void testAddPooledStrings() { 189 NotificationHistory history = new NotificationHistory(); 190 191 List<String> expectedStrings = new ArrayList<>(); 192 for (int i = 1; i <= 10; i++) { 193 HistoricalNotification n = getHistoricalNotification(i); 194 expectedStrings.add(n.getPackage()); 195 expectedStrings.add(n.getChannelName()); 196 expectedStrings.add(n.getChannelId()); 197 if (n.getConversationId() != null) { 198 expectedStrings.add(n.getConversationId()); 199 } 200 history.addNotificationToWrite(n); 201 } 202 203 history.addPooledStrings(expectedStrings); 204 205 String[] actualStrings = history.getPooledStringsToWrite(); 206 assertThat(actualStrings.length).isEqualTo(expectedStrings.size()); 207 String previous = null; 208 for (String actual : actualStrings) { 209 assertThat(expectedStrings).contains(actual); 210 211 if (previous != null) { 212 assertThat(actual).isGreaterThan(previous); 213 } 214 previous = actual; 215 } 216 } 217 218 @Test testRemoveNotificationsFromWrite()219 public void testRemoveNotificationsFromWrite() { 220 NotificationHistory history = new NotificationHistory(); 221 222 List<HistoricalNotification> postRemoveExpectedEntries = new ArrayList<>(); 223 List<String> postRemoveExpectedStrings = new ArrayList<>(); 224 for (int i = 1; i <= 10; i++) { 225 HistoricalNotification n = 226 getHistoricalNotification((i % 2 == 0) ? "pkgEven" : "pkgOdd", i); 227 228 if (i % 2 == 0) { 229 postRemoveExpectedStrings.add(n.getPackage()); 230 postRemoveExpectedStrings.add(n.getChannelName()); 231 postRemoveExpectedStrings.add(n.getChannelId()); 232 if (n.getConversationId() != null) { 233 postRemoveExpectedStrings.add(n.getConversationId()); 234 } 235 postRemoveExpectedEntries.add(n); 236 } 237 238 history.addNotificationToWrite(n); 239 } 240 241 history.poolStringsFromNotifications(); 242 243 assertThat(history.getNotificationsToWrite().size()).isEqualTo(10); 244 // 2 package names and 10 * 2 unique channel names and ids and 5 conversation ids 245 assertThat(history.getPooledStringsToWrite().length).isEqualTo(27); 246 247 history.removeNotificationsFromWrite("pkgOdd"); 248 249 250 // 1 package names and 5 * 2 unique channel names and ids and 5 conversation ids 251 assertThat(history.getPooledStringsToWrite().length).isEqualTo(16); 252 assertThat(history.getNotificationsToWrite()) 253 .containsExactlyElementsIn(postRemoveExpectedEntries); 254 } 255 256 @Test testRemoveNotificationFromWrite()257 public void testRemoveNotificationFromWrite() { 258 NotificationHistory history = new NotificationHistory(); 259 260 List<HistoricalNotification> postRemoveExpectedEntries = new ArrayList<>(); 261 List<String> postRemoveExpectedStrings = new ArrayList<>(); 262 for (int i = 1; i <= 10; i++) { 263 HistoricalNotification n = getHistoricalNotification("pkg", i); 264 265 if (987654323 != n.getPostedTimeMs()) { 266 postRemoveExpectedStrings.add(n.getPackage()); 267 postRemoveExpectedStrings.add(n.getChannelName()); 268 postRemoveExpectedStrings.add(n.getChannelId()); 269 if (n.getConversationId() != null) { 270 postRemoveExpectedStrings.add(n.getConversationId()); 271 } 272 postRemoveExpectedEntries.add(n); 273 } 274 275 history.addNotificationToWrite(n); 276 } 277 278 history.poolStringsFromNotifications(); 279 280 assertThat(history.getNotificationsToWrite().size()).isEqualTo(10); 281 // 1 package name and 20 unique channel names and ids and 5 conversation ids 282 assertThat(history.getPooledStringsToWrite().length).isEqualTo(26); 283 284 history.removeNotificationFromWrite("pkg", 987654323); 285 286 287 // 1 package names and 9 * 2 unique channel names and ids and 4 conversation ids 288 assertThat(history.getPooledStringsToWrite().length).isEqualTo(23); 289 assertThat(history.getNotificationsToWrite()) 290 .containsExactlyElementsIn(postRemoveExpectedEntries); 291 } 292 293 @Test testRemoveConversationNotificationFromWrite()294 public void testRemoveConversationNotificationFromWrite() { 295 NotificationHistory history = new NotificationHistory(); 296 297 List<HistoricalNotification> postRemoveExpectedEntries = new ArrayList<>(); 298 List<String> postRemoveExpectedStrings = new ArrayList<>(); 299 for (int i = 1; i <= 10; i++) { 300 HistoricalNotification n = getHistoricalNotification("pkg", i); 301 302 if (i != 2 && i != 4) { 303 postRemoveExpectedStrings.add(n.getPackage()); 304 postRemoveExpectedStrings.add(n.getChannelName()); 305 postRemoveExpectedStrings.add(n.getChannelId()); 306 if (n.getConversationId() != null) { 307 postRemoveExpectedStrings.add(n.getConversationId()); 308 } 309 postRemoveExpectedEntries.add(n); 310 } 311 312 history.addNotificationToWrite(n); 313 } 314 // add second notification with the same conversation id that will be removed 315 history.addNotificationToWrite(getHistoricalNotification("pkg", 2)); 316 317 history.poolStringsFromNotifications(); 318 319 assertThat(history.getNotificationsToWrite().size()).isEqualTo(11); 320 // 1 package name and 20 unique channel names and ids and 5 conversation ids 321 assertThat(history.getPooledStringsToWrite().length).isEqualTo(26); 322 323 history.removeConversationsFromWrite("pkg", Set.of("convo2", "convo4")); 324 325 // 1 package names and 8 * 2 unique channel names and ids and 3 conversation ids 326 assertThat(history.getPooledStringsToWrite().length).isEqualTo(20); 327 assertThat(history.getNotificationsToWrite()) 328 .containsExactlyElementsIn(postRemoveExpectedEntries); 329 } 330 331 @Test testRemoveChannelFromWrite()332 public void testRemoveChannelFromWrite() { 333 NotificationHistory history = new NotificationHistory(); 334 335 List<HistoricalNotification> postRemoveExpectedEntries = new ArrayList<>(); 336 Set<String> postRemoveExpectedStrings = new HashSet<>(); 337 for (int i = 1; i <= 10; i++) { 338 HistoricalNotification n = getHistoricalNotification("pkg", i); 339 340 // Remove channel numbers 5 and 6 341 if (i != 5 && i != 6) { 342 postRemoveExpectedStrings.add(n.getPackage()); 343 postRemoveExpectedStrings.add(n.getChannelName()); 344 postRemoveExpectedStrings.add(n.getChannelId()); 345 if (n.getConversationId() != null) { 346 postRemoveExpectedStrings.add(n.getConversationId()); 347 } 348 postRemoveExpectedEntries.add(n); 349 } 350 351 history.addNotificationToWrite(n); 352 } 353 // add second notification with the same channel id that will also be removed 354 history.addNotificationToWrite(getHistoricalNotification("pkg", 6)); 355 356 history.poolStringsFromNotifications(); 357 358 assertThat(history.getNotificationsToWrite().size()).isEqualTo(11); 359 // 1 package name and 20 unique channel names and ids and 5 conversation ids 360 assertThat(history.getPooledStringsToWrite().length).isEqualTo(26); 361 362 history.removeChannelFromWrite("pkg", "channelId5"); 363 history.removeChannelFromWrite("pkg", "channelId6"); 364 365 // 1 package names and 8 * 2 unique channel names and ids and 4 conversation ids 366 assertThat(history.getPooledStringsToWrite().length).isEqualTo(21); 367 assertThat(Arrays.asList(history.getPooledStringsToWrite())) 368 .containsExactlyElementsIn(postRemoveExpectedStrings); 369 assertThat(history.getNotificationsToWrite()) 370 .containsExactlyElementsIn(postRemoveExpectedEntries); 371 } 372 373 @Test testParceling()374 public void testParceling() { 375 NotificationHistory history = new NotificationHistory(); 376 377 List<HistoricalNotification> expectedEntries = new ArrayList<>(); 378 for (int i = 10; i >= 1; i--) { 379 HistoricalNotification n = getHistoricalNotification(i); 380 expectedEntries.add(n); 381 history.addNotificationToWrite(n); 382 } 383 history.poolStringsFromNotifications(); 384 385 Parcel parcel = Parcel.obtain(); 386 history.writeToParcel(parcel, 0); 387 parcel.setDataPosition(0); 388 NotificationHistory parceledHistory = NotificationHistory.CREATOR.createFromParcel(parcel); 389 390 assertThat(parceledHistory.getHistoryCount()).isEqualTo(expectedEntries.size()); 391 392 for (int i = 0; i < expectedEntries.size(); i++) { 393 assertThat(parceledHistory.hasNextNotification()).isTrue(); 394 395 HistoricalNotification postParcelNotification = parceledHistory.getNextNotification(); 396 assertThat(postParcelNotification).isEqualTo(expectedEntries.get(i)); 397 } 398 assertThat(parceledHistory.hasNextNotification()).isFalse(); 399 assertThat(parceledHistory.getNextNotification()).isNull(); 400 } 401 } 402