1 /*
2  * Copyright (C) 2020 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.server.notification;
18 
19 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertNotEquals;
23 
24 import android.app.Notification;
25 import android.app.NotificationChannel;
26 import android.os.UserHandle;
27 import android.service.notification.StatusBarNotification;
28 
29 import androidx.test.filters.SmallTest;
30 import androidx.test.runner.AndroidJUnit4;
31 
32 import com.android.server.UiServiceTestCase;
33 
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 
37 
38 @SmallTest
39 @RunWith(AndroidJUnit4.class)
40 public class NotificationRecordLoggerTest extends UiServiceTestCase {
41     private static final int UID = 9999;
42     private static final String CHANNEL_ID = "NotificationRecordLoggerTestChannelId";
43 
getNotification(int id, String tag)44     private NotificationRecord getNotification(int id, String tag) {
45         final String packageName = mContext.getPackageName();
46         NotificationChannel channel = new NotificationChannel(
47                 CHANNEL_ID, CHANNEL_ID, IMPORTANCE_DEFAULT);
48         Notification.Builder nb = new Notification.Builder(mContext, channel.getId());
49         StatusBarNotification sbn = new StatusBarNotification(packageName, packageName, id, tag,
50                 UID, 0, nb.build(), new UserHandle(UID), null,
51                 0);
52         return new NotificationRecord(mContext, sbn, channel);
53     }
54 
getNotificationRecordPair(int id, String tag)55     private NotificationRecordLogger.NotificationRecordPair getNotificationRecordPair(int id,
56             String tag) {
57         return new NotificationRecordLogger.NotificationRecordPair(getNotification(id, tag),
58                 null);
59     }
60 
61     @Test
testSmallHash()62     public void testSmallHash() {
63         assertEquals(0, SmallHash.hash(0));
64         final int maxHash = SmallHash.MAX_HASH;
65         assertEquals(0,
66                 SmallHash.hash(maxHash));
67         assertEquals(0,
68                 SmallHash.hash(17 * maxHash));
69         assertEquals(maxHash - 1,
70                 SmallHash.hash(maxHash - 1));
71         assertEquals(maxHash - 1,
72                 SmallHash.hash(-1));
73     }
74 
75     @Test
testGetNotificationIdHash()76     public void testGetNotificationIdHash() {
77         assertEquals(0,
78                 getNotificationRecordPair(0, null).getNotificationIdHash());
79         assertEquals(1,
80                 getNotificationRecordPair(1, null).getNotificationIdHash());
81         assertEquals(SmallHash.MAX_HASH - 1,
82                 getNotificationRecordPair(-1, null).getNotificationIdHash());
83         final String tag = "someTag";
84         final int hash = SmallHash.hash(tag.hashCode());
85         assertEquals(hash, getNotificationRecordPair(0, tag).getNotificationIdHash());
86         // We xor the tag and hashcode together before compressing the range. The order of
87         // operations doesn't matter if id is small.
88         assertEquals(1 ^ hash,
89                 getNotificationRecordPair(1, tag).getNotificationIdHash());
90         // But it does matter for an id with more 1 bits than fit in the small hash.
91         assertEquals(
92                 SmallHash.hash(-1 ^ tag.hashCode()),
93                 getNotificationRecordPair(-1, tag).getNotificationIdHash());
94         assertNotEquals(-1 ^ hash,
95                 SmallHash.hash(-1 ^ tag.hashCode()));
96     }
97 
98     @Test
testGetChannelIdHash()99     public void testGetChannelIdHash() {
100         assertEquals(
101                 SmallHash.hash(CHANNEL_ID.hashCode()),
102                 getNotificationRecordPair(0, null).getChannelIdHash());
103         assertNotEquals(
104                 SmallHash.hash(CHANNEL_ID.hashCode()),
105                 CHANNEL_ID.hashCode());
106     }
107 
108     @Test
testGetGroupIdHash()109     public void testGetGroupIdHash() {
110         NotificationRecordLogger.NotificationRecordPair p = getNotificationRecordPair(
111                 0, null);
112         assertEquals(0, p.getGroupIdHash());
113         final String group = "someGroup";
114         p.r.setOverrideGroupKey(group);
115         assertEquals(
116                 SmallHash.hash(group.hashCode()),
117                 p.getGroupIdHash());
118     }
119 }
120