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