1 /* 2 * Copyright (C) 2018 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.settings.applications; 18 19 import static android.text.format.DateUtils.DAY_IN_MILLIS; 20 21 import static com.android.settings.applications.AppStateNotificationBridge.FILTER_APP_NOTIFICATION_BLOCKED; 22 import static com.android.settings.applications.AppStateNotificationBridge.FILTER_APP_NOTIFICATION_FREQUENCY; 23 import static com.android.settings.applications.AppStateNotificationBridge.FILTER_APP_NOTIFICATION_RECENCY; 24 import static com.android.settings.applications.AppStateNotificationBridge.FREQUENCY_NOTIFICATION_COMPARATOR; 25 import static com.android.settings.applications.AppStateNotificationBridge.RECENT_NOTIFICATION_COMPARATOR; 26 27 import static com.google.common.truth.Truth.assertThat; 28 29 import static org.junit.Assert.assertFalse; 30 import static org.junit.Assert.assertTrue; 31 import static org.mockito.ArgumentMatchers.any; 32 import static org.mockito.ArgumentMatchers.anyInt; 33 import static org.mockito.ArgumentMatchers.anyLong; 34 import static org.mockito.ArgumentMatchers.anyString; 35 import static org.mockito.ArgumentMatchers.eq; 36 import static org.mockito.Mockito.mock; 37 import static org.mockito.Mockito.verify; 38 import static org.mockito.Mockito.when; 39 40 import android.app.usage.IUsageStatsManager; 41 import android.app.usage.UsageEvents; 42 import android.app.usage.UsageEvents.Event; 43 import android.content.Context; 44 import android.content.pm.ApplicationInfo; 45 import android.content.pm.UserInfo; 46 import android.os.Looper; 47 import android.os.Parcel; 48 import android.os.RemoteException; 49 import android.os.UserHandle; 50 import android.os.UserManager; 51 import android.widget.CompoundButton; 52 import android.widget.Switch; 53 54 import com.android.settings.R; 55 import com.android.settings.applications.AppStateNotificationBridge.NotificationsSentState; 56 import com.android.settings.notification.NotificationBackend; 57 import com.android.settingslib.applications.ApplicationsState; 58 import com.android.settingslib.applications.ApplicationsState.AppEntry; 59 60 import org.junit.Before; 61 import org.junit.Test; 62 import org.junit.runner.RunWith; 63 import org.mockito.Mock; 64 import org.mockito.MockitoAnnotations; 65 import org.robolectric.RobolectricTestRunner; 66 import org.robolectric.RuntimeEnvironment; 67 68 import java.util.ArrayList; 69 import java.util.Arrays; 70 import java.util.List; 71 import java.util.Map; 72 73 @RunWith(RobolectricTestRunner.class) 74 public class AppStateNotificationBridgeTest { 75 76 private static String PKG1 = "pkg1"; 77 private static String PKG2 = "pkg2"; 78 79 @Mock 80 private ApplicationsState.Session mSession; 81 @Mock 82 private ApplicationsState mState; 83 @Mock 84 private IUsageStatsManager mUsageStats; 85 @Mock 86 private UserManager mUserManager; 87 @Mock 88 private NotificationBackend mBackend; 89 private Context mContext; 90 private AppStateNotificationBridge mBridge; 91 92 @Before setUp()93 public void setUp() { 94 MockitoAnnotations.initMocks(this); 95 when(mState.newSession(any())).thenReturn(mSession); 96 when(mState.getBackgroundLooper()).thenReturn(mock(Looper.class)); 97 when(mBackend.getNotificationsBanned(anyString(), anyInt())).thenReturn(true); 98 when(mBackend.enableSwitch(any(), any())).thenReturn(true); 99 // most tests assume no work profile 100 when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{}); 101 mContext = RuntimeEnvironment.application.getApplicationContext(); 102 103 mBridge = new AppStateNotificationBridge(mContext, mState, 104 mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend); 105 } 106 getMockAppEntry(String pkg)107 private AppEntry getMockAppEntry(String pkg) { 108 AppEntry entry = mock(AppEntry.class); 109 entry.info = mock(ApplicationInfo.class); 110 entry.info.packageName = pkg; 111 return entry; 112 } 113 getUsageEvents(List<Event> events)114 private UsageEvents getUsageEvents(List<Event> events) { 115 UsageEvents usageEvents = new UsageEvents(events, new String[] {PKG1, PKG2}); 116 Parcel parcel = Parcel.obtain(); 117 parcel.setDataPosition(0); 118 usageEvents.writeToParcel(parcel, 0); 119 parcel.setDataPosition(0); 120 return UsageEvents.CREATOR.createFromParcel(parcel); 121 } 122 123 @Test testGetAggregatedUsageEvents_noEvents()124 public void testGetAggregatedUsageEvents_noEvents() throws Exception { 125 when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) 126 .thenReturn(mock(UsageEvents.class)); 127 128 assertThat(mBridge.getAggregatedUsageEvents()).isEmpty(); 129 } 130 131 @Test testGetAggregatedUsageEvents_onlyNotificationEvents()132 public void testGetAggregatedUsageEvents_onlyNotificationEvents() throws Exception { 133 List<Event> events = new ArrayList<>(); 134 Event good = new Event(); 135 good.mEventType = Event.NOTIFICATION_INTERRUPTION; 136 good.mPackage = PKG1; 137 good.mTimeStamp = 1; 138 events.add(good); 139 Event bad = new Event(); 140 bad.mEventType = Event.CHOOSER_ACTION; 141 bad.mPackage = PKG1; 142 bad.mTimeStamp = 2; 143 events.add(bad); 144 145 UsageEvents usageEvents = getUsageEvents(events); 146 when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) 147 .thenReturn(usageEvents); 148 149 Map<String, NotificationsSentState> map = mBridge.getAggregatedUsageEvents(); 150 assertThat(map.get(AppStateNotificationBridge.getKey(0, PKG1)).sentCount).isEqualTo(1); 151 } 152 153 @Test testGetAggregatedUsageEvents_multipleEventsAgg()154 public void testGetAggregatedUsageEvents_multipleEventsAgg() throws Exception { 155 List<Event> events = new ArrayList<>(); 156 Event good = new Event(); 157 good.mEventType = Event.NOTIFICATION_INTERRUPTION; 158 good.mPackage = PKG1; 159 good.mTimeStamp = 6; 160 events.add(good); 161 Event good1 = new Event(); 162 good1.mEventType = Event.NOTIFICATION_INTERRUPTION; 163 good1.mPackage = PKG1; 164 good1.mTimeStamp = 1; 165 events.add(good1); 166 167 UsageEvents usageEvents = getUsageEvents(events); 168 when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) 169 .thenReturn(usageEvents); 170 171 Map<String, NotificationsSentState> map = mBridge.getAggregatedUsageEvents(); 172 assertThat(map.get(AppStateNotificationBridge.getKey(0, PKG1)).sentCount).isEqualTo(2); 173 assertThat(map.get(AppStateNotificationBridge.getKey(0, PKG1)).lastSent).isEqualTo(6); 174 } 175 176 @Test testGetAggregatedUsageEvents_multiplePkgs()177 public void testGetAggregatedUsageEvents_multiplePkgs() throws Exception { 178 List<Event> events = new ArrayList<>(); 179 Event good = new Event(); 180 good.mEventType = Event.NOTIFICATION_INTERRUPTION; 181 good.mPackage = PKG1; 182 good.mTimeStamp = 6; 183 events.add(good); 184 Event good1 = new Event(); 185 good1.mEventType = Event.NOTIFICATION_INTERRUPTION; 186 good1.mPackage = PKG2; 187 good1.mTimeStamp = 1; 188 events.add(good1); 189 190 UsageEvents usageEvents = getUsageEvents(events); 191 when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) 192 .thenReturn(usageEvents); 193 194 Map<String, NotificationsSentState> map 195 = mBridge.getAggregatedUsageEvents(); 196 assertThat(map.get(AppStateNotificationBridge.getKey(0, PKG1)).sentCount).isEqualTo(1); 197 assertThat(map.get(AppStateNotificationBridge.getKey(0, PKG2)).sentCount).isEqualTo(1); 198 assertThat(map.get(AppStateNotificationBridge.getKey(0, PKG1)).lastSent).isEqualTo(6); 199 assertThat(map.get(AppStateNotificationBridge.getKey(0, PKG2)).lastSent).isEqualTo(1); 200 } 201 202 @Test testLoadAllExtraInfo_noEvents()203 public void testLoadAllExtraInfo_noEvents() throws RemoteException { 204 when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) 205 .thenReturn(mock(UsageEvents.class)); 206 ArrayList<AppEntry> apps = new ArrayList<>(); 207 apps.add(getMockAppEntry(PKG1)); 208 when(mSession.getAllApps()).thenReturn(apps); 209 210 mBridge.loadAllExtraInfo(); 211 // extra info should exist and blocked status should be populated 212 assertThat(apps.get(0).extraInfo).isNotNull(); 213 verify(mBackend).getNotificationsBanned(PKG1, 0); 214 // but the recent/frequent counts should be 0 so they don't appear on those screens 215 assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentDaily).isEqualTo(0); 216 assertThat(((NotificationsSentState) apps.get(0).extraInfo).lastSent).isEqualTo(0); 217 } 218 219 @Test testLoadAllExtraInfo_multipleEventsAgg()220 public void testLoadAllExtraInfo_multipleEventsAgg() throws RemoteException { 221 List<Event> events = new ArrayList<>(); 222 for (int i = 0; i < 7; i++) { 223 Event good = new Event(); 224 good.mEventType = Event.NOTIFICATION_INTERRUPTION; 225 good.mPackage = PKG1; 226 good.mTimeStamp = i; 227 events.add(good); 228 } 229 230 UsageEvents usageEvents = getUsageEvents(events); 231 when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) 232 .thenReturn(usageEvents); 233 234 ArrayList<AppEntry> apps = new ArrayList<>(); 235 apps.add(getMockAppEntry(PKG1)); 236 when(mSession.getAllApps()).thenReturn(apps); 237 238 mBridge.loadAllExtraInfo(); 239 assertThat(((NotificationsSentState) apps.get(0).extraInfo).sentCount).isEqualTo(7); 240 assertThat(((NotificationsSentState) apps.get(0).extraInfo).lastSent).isEqualTo(6); 241 assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentDaily).isEqualTo(1); 242 assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentWeekly).isEqualTo(0); 243 assertThat(((NotificationsSentState) apps.get(0).extraInfo).blocked).isTrue(); 244 assertThat(((NotificationsSentState) apps.get(0).extraInfo).blockable).isTrue(); 245 } 246 247 @Test testLoadAllExtraInfo_multiplePkgs()248 public void testLoadAllExtraInfo_multiplePkgs() throws RemoteException { 249 List<Event> events = new ArrayList<>(); 250 for (int i = 0; i < 8; i++) { 251 Event good = new Event(); 252 good.mEventType = Event.NOTIFICATION_INTERRUPTION; 253 good.mPackage = PKG1; 254 good.mTimeStamp = i; 255 events.add(good); 256 } 257 Event good1 = new Event(); 258 good1.mEventType = Event.NOTIFICATION_INTERRUPTION; 259 good1.mPackage = PKG2; 260 good1.mTimeStamp = 1; 261 events.add(good1); 262 263 UsageEvents usageEvents = getUsageEvents(events); 264 when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) 265 .thenReturn(usageEvents); 266 267 ArrayList<AppEntry> apps = new ArrayList<>(); 268 apps.add(getMockAppEntry(PKG1)); 269 apps.add(getMockAppEntry(PKG2)); 270 when(mSession.getAllApps()).thenReturn(apps); 271 272 mBridge.loadAllExtraInfo(); 273 assertThat(((NotificationsSentState) apps.get(0).extraInfo).sentCount).isEqualTo(8); 274 assertThat(((NotificationsSentState) apps.get(0).extraInfo).lastSent).isEqualTo(7); 275 assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentWeekly).isEqualTo(0); 276 assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentDaily).isEqualTo(1); 277 278 assertThat(((NotificationsSentState) apps.get(1).extraInfo).sentCount).isEqualTo(1); 279 assertThat(((NotificationsSentState) apps.get(1).extraInfo).lastSent).isEqualTo(1); 280 assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentWeekly).isEqualTo(1); 281 assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentDaily).isEqualTo(0); 282 } 283 284 @Test testLoadAllExtraInfo_multipleUsers()285 public void testLoadAllExtraInfo_multipleUsers() throws RemoteException { 286 // has work profile 287 when(mUserManager.getProfiles(anyInt())).thenReturn(Arrays.asList( 288 new UserInfo(1, "", UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE))); 289 mBridge = new AppStateNotificationBridge(mContext, mState, 290 mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend); 291 292 List<Event> eventsProfileOwner = new ArrayList<>(); 293 for (int i = 0; i < 8; i++) { 294 Event good = new Event(); 295 good.mEventType = Event.NOTIFICATION_INTERRUPTION; 296 good.mPackage = PKG1; 297 good.mTimeStamp = i; 298 eventsProfileOwner.add(good); 299 } 300 301 List<Event> eventsProfile = new ArrayList<>(); 302 for (int i = 0; i < 4; i++) { 303 Event good = new Event(); 304 good.mEventType = Event.NOTIFICATION_INTERRUPTION; 305 good.mPackage = PKG1; 306 good.mTimeStamp = i; 307 eventsProfile.add(good); 308 } 309 310 UsageEvents usageEventsOwner = getUsageEvents(eventsProfileOwner); 311 when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), eq(0), anyString())) 312 .thenReturn(usageEventsOwner); 313 314 UsageEvents usageEventsProfile = getUsageEvents(eventsProfile); 315 when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), eq(1), anyString())) 316 .thenReturn(usageEventsProfile); 317 318 ArrayList<AppEntry> apps = new ArrayList<>(); 319 AppEntry owner = getMockAppEntry(PKG1); 320 owner.info.uid = 1; 321 apps.add(owner); 322 323 AppEntry profile = getMockAppEntry(PKG1); 324 profile.info.uid = UserHandle.PER_USER_RANGE + 1; 325 apps.add(profile); 326 when(mSession.getAllApps()).thenReturn(apps); 327 328 mBridge.loadAllExtraInfo(); 329 330 assertThat(((NotificationsSentState) apps.get(0).extraInfo).sentCount).isEqualTo(8); 331 assertThat(((NotificationsSentState) apps.get(0).extraInfo).lastSent).isEqualTo(7); 332 assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentWeekly).isEqualTo(0); 333 assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentDaily).isEqualTo(1); 334 335 assertThat(((NotificationsSentState) apps.get(1).extraInfo).sentCount).isEqualTo(4); 336 assertThat(((NotificationsSentState) apps.get(1).extraInfo).lastSent).isEqualTo(3); 337 assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentWeekly).isEqualTo(4); 338 assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentDaily).isEqualTo(1); 339 } 340 341 @Test testUpdateExtraInfo_noEvents()342 public void testUpdateExtraInfo_noEvents() throws RemoteException { 343 when(mUsageStats.queryEventsForPackageForUser( 344 anyLong(), anyLong(), anyInt(), anyString(), anyString())) 345 .thenReturn(mock(UsageEvents.class)); 346 AppEntry entry = getMockAppEntry(PKG1); 347 348 mBridge.updateExtraInfo(entry, "", 0); 349 assertThat(entry.extraInfo).isNull(); 350 } 351 352 @Test testUpdateExtraInfo_multipleEventsAgg()353 public void testUpdateExtraInfo_multipleEventsAgg() throws RemoteException { 354 List<Event> events = new ArrayList<>(); 355 for (int i = 0; i < 13; i++) { 356 Event good = new Event(); 357 good.mEventType = Event.NOTIFICATION_INTERRUPTION; 358 good.mPackage = PKG1; 359 good.mTimeStamp = i; 360 events.add(good); 361 } 362 363 UsageEvents usageEvents = getUsageEvents(events); 364 when(mUsageStats.queryEventsForPackageForUser( 365 anyLong(), anyLong(), anyInt(), anyString(), anyString())).thenReturn(usageEvents); 366 367 AppEntry entry = getMockAppEntry(PKG1); 368 mBridge.updateExtraInfo(entry, "", 0); 369 370 assertThat(((NotificationsSentState) entry.extraInfo).sentCount).isEqualTo(13); 371 assertThat(((NotificationsSentState) entry.extraInfo).lastSent).isEqualTo(12); 372 assertThat(((NotificationsSentState) entry.extraInfo).avgSentDaily).isEqualTo(2); 373 assertThat(((NotificationsSentState) entry.extraInfo).avgSentWeekly).isEqualTo(0); 374 assertThat(((NotificationsSentState) entry.extraInfo).blocked).isTrue(); 375 assertThat(((NotificationsSentState) entry.extraInfo).blockable).isTrue(); 376 } 377 378 @Test testSummary_recency()379 public void testSummary_recency() { 380 NotificationsSentState neverSent = new NotificationsSentState(); 381 NotificationsSentState sent = new NotificationsSentState(); 382 sent.lastSent = System.currentTimeMillis() - (2 * DAY_IN_MILLIS); 383 384 assertThat(AppStateNotificationBridge.getSummary( 385 mContext, neverSent, R.id.sort_order_recent_notification)).isEqualTo( 386 mContext.getString(R.string.notifications_sent_never)); 387 assertThat(AppStateNotificationBridge.getSummary( 388 mContext, sent, R.id.sort_order_recent_notification).toString()).contains("2"); 389 } 390 391 @Test testSummary_frequency()392 public void testSummary_frequency() { 393 NotificationsSentState sentRarely = new NotificationsSentState(); 394 sentRarely.avgSentWeekly = 1; 395 NotificationsSentState sentOften = new NotificationsSentState(); 396 sentOften.avgSentDaily = 8; 397 398 assertThat(AppStateNotificationBridge.getSummary( 399 mContext, sentRarely, R.id.sort_order_frequent_notification).toString()) 400 .contains("1"); 401 assertThat(AppStateNotificationBridge.getSummary( 402 mContext, sentRarely, R.id.sort_order_frequent_notification).toString()) 403 .contains("notification "); 404 assertThat(AppStateNotificationBridge.getSummary( 405 mContext, sentRarely, R.id.sort_order_frequent_notification).toString()) 406 .contains("week"); 407 assertThat(AppStateNotificationBridge.getSummary( 408 mContext, sentOften, R.id.sort_order_frequent_notification).toString()) 409 .contains("8"); 410 assertThat(AppStateNotificationBridge.getSummary( 411 mContext, sentOften, R.id.sort_order_frequent_notification).toString()) 412 .contains("notifications"); 413 assertThat(AppStateNotificationBridge.getSummary( 414 mContext, sentOften, R.id.sort_order_frequent_notification).toString()) 415 .contains("day"); 416 } 417 418 @Test testSummary_alpha()419 public void testSummary_alpha() { 420 NotificationsSentState sentRarely = new NotificationsSentState(); 421 sentRarely.avgSentWeekly = 1; 422 assertThat(AppStateNotificationBridge.getSummary( 423 mContext, sentRarely, R.id.sort_order_alpha).toString()) 424 .isEqualTo(""); 425 } 426 427 @Test testFilterRecency()428 public void testFilterRecency() { 429 NotificationsSentState allowState = new NotificationsSentState(); 430 allowState.lastSent = 1; 431 AppEntry allow = mock(AppEntry.class); 432 allow.extraInfo = allowState; 433 434 435 assertTrue(FILTER_APP_NOTIFICATION_RECENCY.filterApp(allow)); 436 437 NotificationsSentState denyState = new NotificationsSentState(); 438 denyState.lastSent = 0; 439 AppEntry deny = mock(AppEntry.class); 440 deny.extraInfo = denyState; 441 442 assertFalse(FILTER_APP_NOTIFICATION_RECENCY.filterApp(deny)); 443 } 444 445 @Test testFilterFrequency()446 public void testFilterFrequency() { 447 NotificationsSentState allowState = new NotificationsSentState(); 448 allowState.sentCount = 1; 449 AppEntry allow = mock(AppEntry.class); 450 allow.extraInfo = allowState; 451 452 assertTrue(FILTER_APP_NOTIFICATION_FREQUENCY.filterApp(allow)); 453 454 NotificationsSentState denyState = new NotificationsSentState(); 455 denyState.sentCount = 0; 456 AppEntry deny = mock(AppEntry.class); 457 deny.extraInfo = denyState; 458 459 assertFalse(FILTER_APP_NOTIFICATION_FREQUENCY.filterApp(deny)); 460 } 461 462 @Test testFilterBlocked()463 public void testFilterBlocked() { 464 NotificationsSentState allowState = new NotificationsSentState(); 465 allowState.blocked = true; 466 AppEntry allow = mock(AppEntry.class); 467 allow.extraInfo = allowState; 468 469 assertTrue(FILTER_APP_NOTIFICATION_BLOCKED.filterApp(allow)); 470 471 NotificationsSentState denyState = new NotificationsSentState(); 472 denyState.blocked = false; 473 AppEntry deny = mock(AppEntry.class); 474 deny.extraInfo = denyState; 475 476 assertFalse(FILTER_APP_NOTIFICATION_BLOCKED.filterApp(deny)); 477 } 478 479 @Test testComparators_nullsNoCrash()480 public void testComparators_nullsNoCrash() { 481 List<AppEntry> entries = new ArrayList<>(); 482 AppEntry a = mock(AppEntry.class); 483 a.label = "1"; 484 AppEntry b = mock(AppEntry.class); 485 b.label = "2"; 486 entries.add(a); 487 entries.add(b); 488 489 entries.sort(RECENT_NOTIFICATION_COMPARATOR); 490 entries.sort(FREQUENCY_NOTIFICATION_COMPARATOR); 491 } 492 493 @Test testRecencyComparator()494 public void testRecencyComparator() { 495 List<AppEntry> entries = new ArrayList<>(); 496 497 NotificationsSentState earlier = new NotificationsSentState(); 498 earlier.lastSent = 1; 499 AppEntry earlyEntry = mock(AppEntry.class); 500 earlyEntry.extraInfo = earlier; 501 entries.add(earlyEntry); 502 503 NotificationsSentState later = new NotificationsSentState(); 504 later.lastSent = 8; 505 AppEntry lateEntry = mock(AppEntry.class); 506 lateEntry.extraInfo = later; 507 entries.add(lateEntry); 508 509 entries.sort(RECENT_NOTIFICATION_COMPARATOR); 510 511 assertThat(entries).containsExactly(lateEntry, earlyEntry); 512 } 513 514 @Test testFrequencyComparator()515 public void testFrequencyComparator() { 516 List<AppEntry> entries = new ArrayList<>(); 517 518 NotificationsSentState notFrequentWeekly = new NotificationsSentState(); 519 notFrequentWeekly.sentCount = 2; 520 AppEntry notFrequentWeeklyEntry = mock(AppEntry.class); 521 notFrequentWeeklyEntry.extraInfo = notFrequentWeekly; 522 entries.add(notFrequentWeeklyEntry); 523 524 NotificationsSentState notFrequentDaily = new NotificationsSentState(); 525 notFrequentDaily.sentCount = 7; 526 AppEntry notFrequentDailyEntry = mock(AppEntry.class); 527 notFrequentDailyEntry.extraInfo = notFrequentDaily; 528 entries.add(notFrequentDailyEntry); 529 530 NotificationsSentState veryFrequentWeekly = new NotificationsSentState(); 531 veryFrequentWeekly.sentCount = 6; 532 AppEntry veryFrequentWeeklyEntry = mock(AppEntry.class); 533 veryFrequentWeeklyEntry.extraInfo = veryFrequentWeekly; 534 entries.add(veryFrequentWeeklyEntry); 535 536 NotificationsSentState veryFrequentDaily = new NotificationsSentState(); 537 veryFrequentDaily.sentCount = 19; 538 AppEntry veryFrequentDailyEntry = mock(AppEntry.class); 539 veryFrequentDailyEntry.extraInfo = veryFrequentDaily; 540 entries.add(veryFrequentDailyEntry); 541 542 entries.sort(FREQUENCY_NOTIFICATION_COMPARATOR); 543 544 assertThat(entries).containsExactly(veryFrequentDailyEntry, notFrequentDailyEntry, 545 veryFrequentWeeklyEntry, notFrequentWeeklyEntry); 546 } 547 548 @Test testSwitchOnChangeListener()549 public void testSwitchOnChangeListener() { 550 Switch toggle = mock(Switch.class); 551 when(toggle.isChecked()).thenReturn(true); 552 when(toggle.isEnabled()).thenReturn(true); 553 554 AppEntry entry = mock(AppEntry.class); 555 entry.info = new ApplicationInfo(); 556 entry.info.packageName = "pkg"; 557 entry.info.uid = 1356; 558 entry.extraInfo = new NotificationsSentState(); 559 560 CompoundButton.OnCheckedChangeListener listener = mBridge.getSwitchOnCheckedListener(entry); 561 listener.onCheckedChanged(toggle, false); 562 563 verify(mBackend).setNotificationsEnabledForPackage( 564 entry.info.packageName, entry.info.uid, false); 565 assertThat(((NotificationsSentState) entry.extraInfo).blocked).isTrue(); 566 } 567 568 @Test testSwitchViews_nullDoesNotCrash()569 public void testSwitchViews_nullDoesNotCrash() { 570 AppStateNotificationBridge.enableSwitch(null); 571 AppStateNotificationBridge.checkSwitch(null); 572 } 573 } 574