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 android.ext.services.notification; 18 19 import static android.app.NotificationManager.IMPORTANCE_HIGH; 20 import static android.app.NotificationManager.IMPORTANCE_MIN; 21 22 import static org.mockito.ArgumentMatchers.any; 23 import static org.mockito.ArgumentMatchers.anyInt; 24 import static org.mockito.ArgumentMatchers.anyLong; 25 import static org.mockito.ArgumentMatchers.anyString; 26 import static org.mockito.Mockito.mock; 27 import static org.mockito.Mockito.never; 28 import static org.mockito.Mockito.times; 29 import static org.mockito.Mockito.verify; 30 import static org.mockito.Mockito.when; 31 32 import android.app.AlarmManager; 33 import android.app.Notification; 34 import android.app.NotificationChannel; 35 import android.app.PendingIntent; 36 import android.content.pm.ApplicationInfo; 37 import android.content.pm.IPackageManager; 38 import android.os.Build; 39 import android.os.Process; 40 import android.os.UserHandle; 41 import android.service.notification.StatusBarNotification; 42 import android.testing.TestableContext; 43 44 import androidx.test.InstrumentationRegistry; 45 import androidx.test.runner.AndroidJUnit4; 46 47 import org.junit.Before; 48 import org.junit.Rule; 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 import org.mockito.Mock; 52 import org.mockito.MockitoAnnotations; 53 54 @RunWith(AndroidJUnit4.class) 55 public class AgingHelperTest { 56 private String mPkg = "pkg"; 57 private int mUid = 2018; 58 59 @Rule 60 public final TestableContext mContext = 61 new TestableContext(InstrumentationRegistry.getTargetContext(), null); 62 63 @Mock 64 private NotificationCategorizer mCategorizer; 65 @Mock 66 private AlarmManager mAlarmManager; 67 @Mock 68 private IPackageManager mPackageManager; 69 @Mock 70 private AgingHelper.Callback mCallback; 71 @Mock 72 private SmsHelper mSmsHelper; 73 74 private AgingHelper mAgingHelper; 75 generateSbn(String channelId)76 private StatusBarNotification generateSbn(String channelId) { 77 Notification n = new Notification.Builder(mContext, channelId) 78 .setContentTitle("foo") 79 .build(); 80 81 return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n, 82 UserHandle.SYSTEM, null, 0); 83 } 84 85 @Before setUp()86 public void setUp() throws Exception { 87 MockitoAnnotations.initMocks(this); 88 mPkg = mContext.getPackageName(); 89 mUid = Process.myUid(); 90 91 ApplicationInfo info = mock(ApplicationInfo.class); 92 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt())) 93 .thenReturn(info); 94 info.targetSdkVersion = Build.VERSION_CODES.P; 95 96 mContext.addMockSystemService(AlarmManager.class, mAlarmManager); 97 98 mAgingHelper = new AgingHelper(mContext, mCategorizer, mCallback); 99 } 100 101 @Test testNoSnoozingOnPost()102 public void testNoSnoozingOnPost() { 103 NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); 104 StatusBarNotification sbn = generateSbn(channel.getId()); 105 NotificationEntry entry = new NotificationEntry( 106 mContext, mPackageManager, sbn, channel, mSmsHelper); 107 108 109 mAgingHelper.onNotificationPosted(entry); 110 verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any()); 111 } 112 113 @Test testPostResetsSnooze()114 public void testPostResetsSnooze() { 115 NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); 116 StatusBarNotification sbn = generateSbn(channel.getId()); 117 NotificationEntry entry = new NotificationEntry( 118 mContext, mPackageManager, sbn, channel, mSmsHelper); 119 120 121 mAgingHelper.onNotificationPosted(entry); 122 verify(mAlarmManager, times(1)).cancel(any(PendingIntent.class)); 123 } 124 125 @Test testSnoozingOnSeen()126 public void testSnoozingOnSeen() { 127 NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); 128 StatusBarNotification sbn = generateSbn(channel.getId()); 129 NotificationEntry entry = new NotificationEntry( 130 mContext, mPackageManager, sbn, channel, mSmsHelper); 131 entry.setSeen(); 132 when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE); 133 134 mAgingHelper.onNotificationSeen(entry); 135 verify(mAlarmManager, times(1)).setExactAndAllowWhileIdle(anyInt(), anyLong(), any()); 136 } 137 138 @Test testNoSnoozingOnSeenUserLocked()139 public void testNoSnoozingOnSeenUserLocked() { 140 NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); 141 channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE); 142 StatusBarNotification sbn = generateSbn(channel.getId()); 143 NotificationEntry entry = new NotificationEntry( 144 mContext, mPackageManager, sbn, channel, mSmsHelper); 145 when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE); 146 147 mAgingHelper.onNotificationSeen(entry); 148 verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any()); 149 } 150 151 @Test testNoSnoozingOnSeenAlreadyLow()152 public void testNoSnoozingOnSeenAlreadyLow() { 153 NotificationEntry entry = mock(NotificationEntry.class); 154 when(entry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_HIGH)); 155 when(entry.getImportance()).thenReturn(IMPORTANCE_MIN); 156 157 mAgingHelper.onNotificationSeen(entry); 158 verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any()); 159 } 160 } 161