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.systemui.statusbar.notification.icon; 18 19 import android.app.ActivityManager; 20 import android.app.Notification; 21 import android.app.NotificationChannel 22 import android.app.NotificationManager.IMPORTANCE_DEFAULT 23 import android.app.Person 24 import android.content.pm.LauncherApps 25 import android.content.pm.ShortcutInfo 26 import android.graphics.drawable.Drawable 27 import android.graphics.drawable.Icon 28 import android.os.SystemClock 29 import android.os.UserHandle 30 import android.testing.AndroidTestingRunner; 31 import androidx.test.InstrumentationRegistry 32 import androidx.test.filters.SmallTest 33 import com.android.systemui.SysuiTestCase 34 import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapperTest.Companion.any 35 import com.android.systemui.statusbar.notification.collection.NotificationEntry 36 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder 37 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection 38 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow 39 import org.junit.Assert.assertEquals 40 import org.junit.Before 41 import org.junit.Test 42 43 import org.junit.runner.RunWith; 44 import org.mockito.Mock 45 import org.mockito.Mockito.`when` 46 import org.mockito.Mockito.anyInt 47 import org.mockito.MockitoAnnotations 48 49 @SmallTest 50 @RunWith(AndroidTestingRunner::class) 51 class IconManagerTest: SysuiTestCase() { 52 companion object { 53 private const val TEST_PACKAGE_NAME = "test"; 54 private const val TEST_UID = 0; 55 } 56 57 58 private var id = 0 59 private val context = InstrumentationRegistry.getTargetContext(); 60 @Mock private lateinit var shortcut: ShortcutInfo 61 @Mock private lateinit var shortcutIc: Icon 62 @Mock private lateinit var messageIc: Icon 63 @Mock private lateinit var largeIc: Icon 64 @Mock private lateinit var smallIc: Icon 65 @Mock private lateinit var drawable: Drawable 66 @Mock private lateinit var row: ExpandableNotificationRow 67 68 @Mock private lateinit var notifCollection: CommonNotifCollection 69 @Mock private lateinit var launcherApps: LauncherApps 70 71 private val iconBuilder = IconBuilder(context) 72 73 private lateinit var iconManager: IconManager 74 75 @Before 76 fun setUp() { 77 MockitoAnnotations.initMocks(this) 78 79 `when`(shortcutIc.loadDrawableAsUser(any(), anyInt())).thenReturn(drawable) 80 `when`(messageIc.loadDrawableAsUser(any(), anyInt())).thenReturn(drawable) 81 `when`(largeIc.loadDrawableAsUser(any(), anyInt())).thenReturn(drawable) 82 `when`(smallIc.loadDrawableAsUser(any(), anyInt())).thenReturn(drawable) 83 84 `when`(shortcut.icon).thenReturn(shortcutIc) 85 `when`(launcherApps.getShortcutIcon(shortcut)).thenReturn(shortcutIc) 86 87 iconManager = IconManager(notifCollection, launcherApps, iconBuilder) 88 } 89 90 @Test 91 fun testCreateIcons_importantConversation_shortcutIcon() { 92 val entry = notificationEntry(true, true, true) 93 entry?.channel?.isImportantConversation = true 94 entry?.let { 95 iconManager.createIcons(it) 96 } 97 assertEquals(entry?.icons?.statusBarIcon?.sourceIcon, shortcutIc) 98 } 99 100 @Test 101 fun testCreateIcons_importantConversation_messageIcon() { 102 val entry = notificationEntry(false, true, true) 103 entry?.channel?.isImportantConversation = true 104 entry?.let { 105 iconManager.createIcons(it) 106 } 107 assertEquals(entry?.icons?.statusBarIcon?.sourceIcon, messageIc) 108 } 109 110 @Test 111 fun testCreateIcons_importantConversation_largeIcon() { 112 val entry = notificationEntry(false, false, true) 113 entry?.channel?.isImportantConversation = true 114 entry?.let { 115 iconManager.createIcons(it) 116 } 117 assertEquals(entry?.icons?.statusBarIcon?.sourceIcon, largeIc) 118 } 119 120 @Test 121 fun testCreateIcons_importantConversation_smallIcon() { 122 val entry = notificationEntry(false, false, false) 123 entry?.channel?.isImportantConversation = true 124 entry?.let { 125 iconManager.createIcons(it) 126 } 127 assertEquals(entry?.icons?.statusBarIcon?.sourceIcon, smallIc) 128 } 129 130 @Test 131 fun testCreateIcons_notImportantConversation() { 132 val entry = notificationEntry(true, true, true) 133 entry?.let { 134 iconManager.createIcons(it) 135 } 136 assertEquals(entry?.icons?.statusBarIcon?.sourceIcon, smallIc) 137 } 138 139 @Test 140 fun testCreateIcons_sensitiveImportantConversation() { 141 val entry = notificationEntry(true, false, false) 142 entry?.setSensitive(true, true); 143 entry?.channel?.isImportantConversation = true 144 entry?.let { 145 iconManager.createIcons(it) 146 } 147 assertEquals(entry?.icons?.statusBarIcon?.sourceIcon, shortcutIc) 148 assertEquals(entry?.icons?.shelfIcon?.sourceIcon, smallIc) 149 assertEquals(entry?.icons?.aodIcon?.sourceIcon, smallIc) 150 } 151 152 @Test 153 fun testUpdateIcons_sensitivityChange() { 154 val entry = notificationEntry(true, false, false) 155 entry?.channel?.isImportantConversation = true 156 entry?.setSensitive(true, true); 157 entry?.let { 158 iconManager.createIcons(it) 159 } 160 assertEquals(entry?.icons?.aodIcon?.sourceIcon, smallIc) 161 entry?.setSensitive(false, false); 162 entry?.let { 163 iconManager.updateIcons(it) 164 } 165 assertEquals(entry?.icons?.shelfIcon?.sourceIcon, shortcutIc) 166 } 167 168 private fun notificationEntry( 169 hasShortcut: Boolean, 170 hasMessage: Boolean, 171 hasLargeIcon: Boolean 172 ): NotificationEntry? { 173 val n = Notification.Builder(mContext, "id") 174 .setSmallIcon(smallIc) 175 .setContentTitle("Title") 176 .setContentText("Text") 177 178 if (hasMessage) { 179 n.style = Notification.MessagingStyle("") 180 .addMessage(Notification.MessagingStyle.Message( 181 "", 182 SystemClock.currentThreadTimeMillis(), 183 Person.Builder().setIcon(messageIc).build() 184 )) 185 } 186 187 if (hasLargeIcon) { 188 n.setLargeIcon(largeIc) 189 } 190 191 val builder = NotificationEntryBuilder() 192 .setPkg(TEST_PACKAGE_NAME) 193 .setOpPkg(TEST_PACKAGE_NAME) 194 .setUid(TEST_UID) 195 .setId(id++) 196 .setNotification(n.build()) 197 .setChannel(NotificationChannel("id", "", IMPORTANCE_DEFAULT)) 198 .setUser(UserHandle(ActivityManager.getCurrentUser())) 199 200 if (hasShortcut) { 201 builder.setShortcutInfo(shortcut) 202 } 203 204 val entry = builder.build() 205 entry.row = row 206 entry.setSensitive(false, true); 207 return entry 208 } 209 } 210