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