1 /* 2 * Copyright (C) 2023 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.localepicker; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import android.content.Context; 22 import android.os.LocaleList; 23 import android.os.SystemClock; 24 25 import org.junit.After; 26 import org.junit.Before; 27 import org.junit.Test; 28 import org.junit.runner.RunWith; 29 import org.mockito.MockitoAnnotations; 30 import org.robolectric.RobolectricTestRunner; 31 import org.robolectric.RuntimeEnvironment; 32 33 import java.util.Calendar; 34 import java.util.Set; 35 36 @RunWith(RobolectricTestRunner.class) 37 public class NotificationControllerTest { 38 private Context mContext; 39 private LocaleNotificationDataManager mDataManager; 40 private NotificationController mNotificationController; 41 42 @Before setUp()43 public void setUp() throws Exception { 44 MockitoAnnotations.initMocks(this); 45 mContext = RuntimeEnvironment.application; 46 mNotificationController = NotificationController.getInstance(mContext); 47 mDataManager = mNotificationController.getDataManager(); 48 LocaleList.setDefault(LocaleList.forLanguageTags("en-CA")); 49 } 50 51 @After tearDown()52 public void tearDown() { 53 mDataManager.clearLocaleNotificationMap(); 54 } 55 56 @Test incrementDismissCount_addOne()57 public void incrementDismissCount_addOne() throws Exception { 58 String enUS = "en-US"; 59 Set<Integer> uidSet = Set.of(100, 101); 60 long lastNotificationTime = Calendar.getInstance().getTimeInMillis(); 61 int id = (int) SystemClock.uptimeMillis(); 62 initSharedPreference(enUS, uidSet, 0, 1, lastNotificationTime, id); 63 64 mNotificationController.incrementDismissCount(enUS); 65 NotificationInfo result = mDataManager.getNotificationInfo(enUS); 66 67 assertThat(result.getDismissCount()).isEqualTo(1); // dismissCount increments 68 assertThat(result.getUidCollection()).isEqualTo(uidSet); 69 assertThat(result.getNotificationCount()).isEqualTo(1); 70 assertThat(result.getLastNotificationTimeMs()).isEqualTo(lastNotificationTime); 71 assertThat(result.getNotificationId()).isEqualTo(id); 72 } 73 74 @Test testRemoveNotificationInfo_removed()75 public void testRemoveNotificationInfo_removed() throws Exception { 76 String enUS = "en-US"; 77 Set<Integer> uidSet = Set.of(100, 101); 78 long lastNotificationTime = Calendar.getInstance().getTimeInMillis(); 79 int id = (int) SystemClock.uptimeMillis(); 80 initSharedPreference(enUS, uidSet, 0, 1, lastNotificationTime, id); 81 82 mNotificationController.removeNotificationInfo(enUS); 83 84 assertThat(mDataManager.getNotificationInfo(enUS)).isNull(); 85 } 86 87 @Test testShouldTriggerNotification_inSystemLocale_returnFalse()88 public void testShouldTriggerNotification_inSystemLocale_returnFalse() throws Exception { 89 int uid = 102; 90 // As checking whether app's locales exist in system locales, both app locales and system 91 // locales have to remove the u extension first when doing the comparison. The following 92 // three locales are all in the system locale after removing the u extension so it's 93 // unnecessary to trigger a notification for the suggestion. 94 String locale1 = "en-CA"; 95 String locale2 = "ar-JO-u-nu-latn"; 96 String locale3 = "ar-JO"; 97 98 LocaleList.setDefault( 99 LocaleList.forLanguageTags("en-CA-u-mu-fahrenhe,ar-JO-u-mu-fahrenhe-nu-latn")); 100 101 assertThat(mNotificationController.shouldTriggerNotification(uid, locale1)).isFalse(); 102 assertThat(mNotificationController.shouldTriggerNotification(uid, locale2)).isFalse(); 103 assertThat(mNotificationController.shouldTriggerNotification(uid, locale3)).isFalse(); 104 } 105 106 @Test testShouldTriggerNotification_noNotification_returnFalse()107 public void testShouldTriggerNotification_noNotification_returnFalse() throws Exception { 108 int uid = 100; 109 String locale = "en-US"; 110 111 boolean triggered = mNotificationController.shouldTriggerNotification(uid, locale); 112 113 assertThat(triggered).isFalse(); 114 } 115 116 @Test testShouldTriggerNotification_return1stTrue()117 public void testShouldTriggerNotification_return1stTrue() throws Exception { 118 // Initialze proto with en-US locale. Its uid contains 100. 119 Set<Integer> uidSet = Set.of(100); 120 String locale = "en-US"; 121 long lastNotificationTime = 0L; 122 int notificationId = 0; 123 initSharedPreference(locale, uidSet, 0, 1, lastNotificationTime, notificationId); 124 125 // When the second app is configured to "en-US", the notification is triggered. 126 int uid = 101; 127 boolean triggered = mNotificationController.shouldTriggerNotification(uid, locale); 128 129 assertThat(triggered).isTrue(); 130 } 131 132 @Test testShouldTriggerNotification_returnFalse_dueToOddCount()133 public void testShouldTriggerNotification_returnFalse_dueToOddCount() throws Exception { 134 // Initialze proto with en-US locale. Its uid contains 100,101. 135 Set<Integer> uidSet = Set.of(100, 101); 136 String locale = "en-US"; 137 long lastNotificationTime = Calendar.getInstance().getTimeInMillis(); 138 int id = (int) SystemClock.uptimeMillis(); 139 initSharedPreference(locale, uidSet, 0, 1, lastNotificationTime, id); 140 141 // When the other app is configured to "en-US", the notification is not triggered because 142 // the app count is odd. 143 int uid = 102; 144 boolean triggered = mNotificationController.shouldTriggerNotification(uid, locale); 145 146 assertThat(triggered).isFalse(); 147 } 148 149 @Test testShouldTriggerNotification_returnFalse_dueToFrequency()150 public void testShouldTriggerNotification_returnFalse_dueToFrequency() throws Exception { 151 // Initialze proto with en-US locale. Its uid contains 100,101,102. 152 Set<Integer> uidSet = Set.of(100, 101, 102); 153 String locale = "en-US"; 154 long lastNotificationTime = Calendar.getInstance().getTimeInMillis(); 155 int id = (int) SystemClock.uptimeMillis(); 156 initSharedPreference(locale, uidSet, 0, 1, lastNotificationTime, id); 157 158 // When the other app is configured to "en-US", the notification is not triggered because it 159 // is too frequent. 160 int uid = 103; 161 boolean triggered = mNotificationController.shouldTriggerNotification(uid, locale); 162 163 assertThat(triggered).isFalse(); 164 } 165 166 @Test testShouldTriggerNotification_return2ndTrue()167 public void testShouldTriggerNotification_return2ndTrue() throws Exception { 168 // Initialze proto with en-US locale. Its uid contains 100,101,102,103,104. 169 Set<Integer> uidSet = Set.of(100, 101, 102, 103, 104); 170 String locale = "en-US"; 171 int id = (int) SystemClock.uptimeMillis(); 172 Calendar time = Calendar.getInstance(); 173 time.add(Calendar.MINUTE, 86400 * 8 * (-1)); 174 long lastNotificationTime = time.getTimeInMillis(); 175 initSharedPreference(locale, uidSet, 0, 1, lastNotificationTime, id); 176 177 // When the other app is configured to "en-US", the notification is triggered. 178 int uid = 105; 179 boolean triggered = mNotificationController.shouldTriggerNotification(uid, locale); 180 181 assertThat(triggered).isTrue(); 182 } 183 initSharedPreference(String locale, Set<Integer> uidCollection, int dismissCount, int notificationCount, long lastNotificationTime, int notificationId)184 private void initSharedPreference(String locale, Set<Integer> uidCollection, int dismissCount, 185 int notificationCount, long lastNotificationTime, int notificationId) 186 throws Exception { 187 NotificationInfo info = new NotificationInfo(uidCollection, notificationCount, dismissCount, 188 lastNotificationTime, notificationId); 189 mDataManager.putNotificationInfo(locale, info); 190 } 191 } 192