1 /*
2  *  Copyright (C) 2022 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 
18 package com.android.systemui.statusbar.notification.collection
19 
20 import android.app.Notification
21 import android.app.NotificationManager
22 import android.content.pm.ApplicationInfo
23 import android.content.pm.PackageManager
24 import android.os.Bundle
25 import android.os.UserHandle
26 import android.service.notification.NotificationListenerService.Ranking
27 import android.service.notification.StatusBarNotification
28 import androidx.test.ext.junit.runners.AndroidJUnit4
29 import androidx.test.filters.SmallTest
30 import com.android.systemui.SysuiTestCase
31 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
32 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
33 import com.android.systemui.util.mockito.mock
34 import com.android.systemui.util.mockito.withArgCaptor
35 import junit.framework.Assert.assertEquals
36 import org.junit.Before
37 import org.junit.Test
38 import org.junit.runner.RunWith
39 import org.mockito.Mockito.anyInt
40 import org.mockito.Mockito.anyString
41 import org.mockito.Mockito.eq
42 import org.mockito.Mockito.verify
43 import org.mockito.Mockito.verifyZeroInteractions
44 import org.mockito.Mockito.`when` as whenever
45 
46 private const val SDK_VERSION = 33
47 private const val PACKAGE = "pkg"
48 private const val USER_ID = -1
49 
50 @SmallTest
51 @RunWith(AndroidJUnit4::class)
52 class TargetSdkResolverTest : SysuiTestCase() {
53     private val packageManager: PackageManager = mock()
<lambda>null54     private val applicationInfo = ApplicationInfo().apply { targetSdkVersion = SDK_VERSION }
55 
56     private lateinit var targetSdkResolver: TargetSdkResolver
57     private lateinit var notifListener: NotifCollectionListener
58 
59     @Before
setUpnull60     fun setUp() {
61         targetSdkResolver = TargetSdkResolver(mContext)
62         mContext.setMockPackageManager(packageManager)
63 
64         val notifCollection: CommonNotifCollection = mock()
65         targetSdkResolver.initialize(notifCollection)
66         notifListener = withArgCaptor {
67             verify(notifCollection).addCollectionListener(capture())
68         }
69     }
70 
71     @Test
resolveFromNotificationExtrasnull72     fun resolveFromNotificationExtras() {
73         val extras = Bundle().apply {
74             putParcelable(Notification.EXTRA_BUILDER_APPLICATION_INFO, applicationInfo)
75         }
76         val notification = Notification().apply { this.extras = extras }
77         val sbn = createSbn(notification)
78         val entry = createNotificationEntry(sbn)
79 
80         notifListener.onEntryBind(entry, sbn)
81 
82         assertEquals(SDK_VERSION, entry.targetSdk)
83         verifyZeroInteractions(packageManager)
84     }
85 
86     @Test
resolveFromPackageManagernull87     fun resolveFromPackageManager() {
88         val sbn = createSbn(Notification())
89         val entry = createNotificationEntry(sbn)
90         whenever(packageManager.getApplicationInfo(anyString(), anyInt()))
91                 .thenReturn(applicationInfo)
92 
93         notifListener.onEntryBind(entry, sbn)
94 
95         assertEquals(SDK_VERSION, entry.targetSdk)
96         verify(packageManager).getApplicationInfo(eq(PACKAGE), anyInt())
97     }
98 
99     @Test
resolveFromPackageManager_andPackageManagerCrashesnull100     fun resolveFromPackageManager_andPackageManagerCrashes() {
101         val sbn = createSbn(Notification())
102         val entry = createNotificationEntry(sbn)
103         whenever(packageManager.getApplicationInfo(anyString(), anyInt()))
104                 .thenThrow(PackageManager.NameNotFoundException())
105 
106         notifListener.onEntryBind(entry, sbn)
107 
108         assertEquals(0, entry.targetSdk)
109         verify(packageManager).getApplicationInfo(eq(PACKAGE), anyInt())
110     }
111 
createSbnnull112     private fun createSbn(notification: Notification) = StatusBarNotification(
113             PACKAGE, "opPkg", 0, "tag", 0, 0,
114             notification, UserHandle(USER_ID), "", 0
115     )
116 
117     private fun createNotificationEntry(sbn: StatusBarNotification) =
118             NotificationEntry(sbn, createRanking(sbn.key), 0)
119 
120     private fun createRanking(key: String) = Ranking().apply {
121         populate(
122                 key,
123                 /* rank = */ 0,
124                 /* matchesInterruptionFilter = */ false,
125                 /* visibilityOverride = */ 0,
126                 /* suppressedVisualEffects = */ 0,
127                 /* importance = */ NotificationManager.IMPORTANCE_DEFAULT,
128                 /* explanation = */ null,
129                 /* overrideGroupKey = */ null,
130                 /* channel = */ null,
131                 /* overridePeople = */ null,
132                 /* snoozeCriteria = */ null,
133                 /* showBadge = */ true,
134                 /* userSentiment = */ 0,
135                 /* hidden = */ false,
136                 /* lastAudiblyAlertedMs = */ -1,
137                 /* noisy = */ false,
138                 /* smartActions = */ null,
139                 /* smartReplies = */ null,
140                 /* canBubble = */ false,
141                 /* isTextChanged = */ false,
142                 /* isConversation = */ false,
143                 /* shortcutInfo = */ null,
144                 /* rankingAdjustment = */ 0,
145                 /* isBubble = */ false,
146                 /* proposedImportance = */ 0,
147                 /* sensitiveContent = */ false
148         )
149     }
150 }
151