1 /* 2 * Copyright (C) 2024 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.launcher3.pm 18 19 import android.content.pm.ApplicationInfo 20 import android.content.pm.ApplicationInfo.FLAG_INSTALLED 21 import android.content.pm.ApplicationInfo.FLAG_SYSTEM 22 import android.content.pm.LauncherApps 23 import android.content.pm.PackageInstaller 24 import android.content.pm.PackageManager 25 import android.graphics.Bitmap 26 import android.os.Process.myUserHandle 27 import android.os.UserHandle 28 import androidx.test.ext.junit.runners.AndroidJUnit4 29 import androidx.test.filters.SmallTest 30 import com.android.launcher3.LauncherPrefs 31 import com.android.launcher3.LauncherPrefs.Companion.PROMISE_ICON_IDS 32 import com.android.launcher3.util.Executors.MODEL_EXECUTOR 33 import com.android.launcher3.util.IntArray 34 import com.android.launcher3.util.LauncherModelHelper 35 import com.android.launcher3.util.TestUtil 36 import com.google.common.truth.Truth.assertThat 37 import org.junit.Before 38 import org.junit.Test 39 import org.junit.runner.RunWith 40 import org.mockito.kotlin.any 41 import org.mockito.kotlin.doReturn 42 import org.mockito.kotlin.eq 43 import org.mockito.kotlin.mock 44 import org.mockito.kotlin.spy 45 import org.mockito.kotlin.whenever 46 47 @SmallTest 48 @RunWith(AndroidJUnit4::class) 49 class InstallSessionHelperTest { 50 51 private val launcherModelHelper = LauncherModelHelper() 52 private val sandboxContext = spy(launcherModelHelper.sandboxContext) 53 private val packageManager = sandboxContext.packageManager 54 private val expectedAppPackage = "expectedAppPackage" 55 private val expectedInstallerPackage = sandboxContext.packageName 56 private val mockPackageInstaller: PackageInstaller = mock() 57 58 private lateinit var installSessionHelper: InstallSessionHelper 59 private lateinit var launcherApps: LauncherApps 60 61 @Before setupnull62 fun setup() { 63 whenever(packageManager.packageInstaller).thenReturn(mockPackageInstaller) 64 launcherApps = sandboxContext.spyService(LauncherApps::class.java) 65 installSessionHelper = InstallSessionHelper(sandboxContext) 66 } 67 68 @Test getActiveSessions fetches verified install sessions from LauncherAppsnull69 fun `getActiveSessions fetches verified install sessions from LauncherApps`() { 70 // Given 71 val expectedVerifiedSession1 = 72 PackageInstaller.SessionInfo().apply { 73 sessionId = 0 74 installerPackageName = expectedInstallerPackage 75 appPackageName = expectedAppPackage 76 userId = myUserHandle().identifier 77 } 78 val expectedVerifiedSession2 = 79 PackageInstaller.SessionInfo().apply { 80 sessionId = 1 81 installerPackageName = expectedInstallerPackage 82 appPackageName = "app2" 83 userId = myUserHandle().identifier 84 } 85 val expectedSessions = listOf(expectedVerifiedSession1, expectedVerifiedSession2) 86 whenever(launcherApps.allPackageInstallerSessions).thenReturn(expectedSessions) 87 // When 88 val actualSessions = installSessionHelper.getActiveSessions() 89 // Then 90 assertThat(actualSessions.values.toList()).isEqualTo(expectedSessions) 91 } 92 93 @Test getActiveSessionInfo fetches verified install sessions for given user and pkgnull94 fun `getActiveSessionInfo fetches verified install sessions for given user and pkg`() { 95 // Given 96 val expectedVerifiedSession = 97 PackageInstaller.SessionInfo().apply { 98 installerPackageName = expectedInstallerPackage 99 appPackageName = expectedAppPackage 100 userId = myUserHandle().identifier 101 } 102 whenever(launcherApps.allPackageInstallerSessions) 103 .thenReturn(listOf(expectedVerifiedSession)) 104 // When 105 val actualSession = 106 installSessionHelper.getActiveSessionInfo(myUserHandle(), expectedAppPackage) 107 // Then 108 assertThat(actualSession).isEqualTo(expectedVerifiedSession) 109 } 110 111 @Test getVerifiedSessionInfo verifies and returns session for given idnull112 fun `getVerifiedSessionInfo verifies and returns session for given id`() { 113 // Given 114 val expectedSession = 115 PackageInstaller.SessionInfo().apply { 116 sessionId = 1 117 installerPackageName = expectedInstallerPackage 118 appPackageName = expectedAppPackage 119 userId = myUserHandle().identifier 120 } 121 whenever(mockPackageInstaller.getSessionInfo(1)).thenReturn(expectedSession) 122 // When 123 val actualSession = installSessionHelper.getVerifiedSessionInfo(1) 124 // Then 125 assertThat(actualSession).isEqualTo(expectedSession) 126 } 127 128 @Test isTrustedPackage returns true if LauncherApps finds ApplicationInfonull129 fun `isTrustedPackage returns true if LauncherApps finds ApplicationInfo`() { 130 // Given 131 val expectedApplicationInfo = 132 ApplicationInfo().apply { flags = FLAG_SYSTEM or FLAG_INSTALLED } 133 doReturn(expectedApplicationInfo) 134 .whenever(launcherApps) 135 .getApplicationInfo(eq(expectedAppPackage), any(), eq(UserHandle(0))) 136 // When 137 val actualResult = installSessionHelper.isTrustedPackage(expectedAppPackage, UserHandle(0)) 138 // Then 139 assertThat(actualResult).isTrue() 140 } 141 142 @Test getAllVerifiedSessions verifies and returns all active install sessionsnull143 fun `getAllVerifiedSessions verifies and returns all active install sessions`() { 144 // Given 145 val expectedVerifiedSession1 = 146 PackageInstaller.SessionInfo().apply { 147 sessionId = 0 148 installerPackageName = expectedInstallerPackage 149 appPackageName = expectedAppPackage 150 userId = myUserHandle().identifier 151 } 152 val expectedVerifiedSession2 = 153 PackageInstaller.SessionInfo().apply { 154 sessionId = 1 155 installerPackageName = expectedInstallerPackage 156 appPackageName = "app2" 157 userId = myUserHandle().identifier 158 } 159 val expectedSessions = listOf(expectedVerifiedSession1, expectedVerifiedSession2) 160 whenever(launcherApps.allPackageInstallerSessions).thenReturn(expectedSessions) 161 // When 162 val actualSessions = installSessionHelper.allVerifiedSessions 163 // Then 164 assertThat(actualSessions).isEqualTo(expectedSessions) 165 } 166 167 @Test promiseIconAddedForId returns true if there is a promiseIcon with the session idnull168 fun `promiseIconAddedForId returns true if there is a promiseIcon with the session id`() { 169 // Given 170 val expectedIdString = IntArray().apply { add(1) }.toConcatString() 171 LauncherPrefs.get(sandboxContext).putSync(Pair(PROMISE_ICON_IDS, expectedIdString)) 172 val expectedSession = 173 PackageInstaller.SessionInfo().apply { 174 sessionId = 1 175 installerPackageName = expectedInstallerPackage 176 appPackageName = "app2" 177 userId = myUserHandle().identifier 178 } 179 whenever(launcherApps.allPackageInstallerSessions).thenReturn(listOf(expectedSession)) 180 // When 181 var actualResult = false 182 TestUtil.runOnExecutorSync(MODEL_EXECUTOR) { 183 actualResult = installSessionHelper.promiseIconAddedForId(1) 184 } 185 // Then 186 assertThat(actualResult).isTrue() 187 } 188 189 @Test removePromiseIconId removes promiseIconId for given Session idnull190 fun `removePromiseIconId removes promiseIconId for given Session id`() { 191 // Given 192 val expectedIdString = IntArray().apply { add(1) }.toConcatString() 193 LauncherPrefs.get(sandboxContext).putSync(Pair(PROMISE_ICON_IDS, expectedIdString)) 194 val expectedSession = 195 PackageInstaller.SessionInfo().apply { 196 sessionId = 1 197 installerPackageName = expectedInstallerPackage 198 appPackageName = "app2" 199 userId = myUserHandle().identifier 200 } 201 whenever(launcherApps.allPackageInstallerSessions).thenReturn(listOf(expectedSession)) 202 // When 203 var actualResult = true 204 TestUtil.runOnExecutorSync(MODEL_EXECUTOR) { 205 installSessionHelper.removePromiseIconId(1) 206 actualResult = installSessionHelper.promiseIconAddedForId(1) 207 } 208 // Then 209 assertThat(actualResult).isFalse() 210 } 211 212 @Test tryQueuePromiseAppIcon will update promise icon ids from eligible sessionsnull213 fun `tryQueuePromiseAppIcon will update promise icon ids from eligible sessions`() { 214 // Given 215 val expectedIdString = IntArray().apply { add(1) }.toConcatString() 216 LauncherPrefs.get(sandboxContext).putSync(Pair(PROMISE_ICON_IDS, expectedIdString)) 217 val expectedSession = 218 PackageInstaller.SessionInfo().apply { 219 sessionId = 1 220 installerPackageName = expectedInstallerPackage 221 appPackageName = "appPackage" 222 userId = myUserHandle().identifier 223 appIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8) 224 appLabel = "appLabel" 225 installReason = PackageManager.INSTALL_REASON_USER 226 } 227 whenever(launcherApps.allPackageInstallerSessions).thenReturn(listOf(expectedSession)) 228 // When 229 var wasPromiseIconAdded = false 230 var actualPromiseIconIds = "" 231 TestUtil.runOnExecutorSync(MODEL_EXECUTOR) { 232 installSessionHelper.removePromiseIconId(1) 233 installSessionHelper.tryQueuePromiseAppIcon(expectedSession) 234 wasPromiseIconAdded = installSessionHelper.promiseIconAddedForId(1) 235 actualPromiseIconIds = LauncherPrefs.get(sandboxContext).get(PROMISE_ICON_IDS) 236 } 237 // Then 238 assertThat(wasPromiseIconAdded).isTrue() 239 assertThat(actualPromiseIconIds).isEqualTo(expectedIdString) 240 } 241 242 @Test verifySessionInfo is true if can verify given SessionInfonull243 fun `verifySessionInfo is true if can verify given SessionInfo`() { 244 // Given 245 val expectedIdString = IntArray().apply { add(1) }.toConcatString() 246 LauncherPrefs.get(sandboxContext).putSync(Pair(PROMISE_ICON_IDS, expectedIdString)) 247 val expectedSession = 248 PackageInstaller.SessionInfo().apply { 249 sessionId = 1 250 installerPackageName = expectedInstallerPackage 251 appPackageName = "appPackage" 252 userId = myUserHandle().identifier 253 appIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8) 254 appLabel = "appLabel" 255 installReason = PackageManager.INSTALL_REASON_USER 256 } 257 whenever(launcherApps.allPackageInstallerSessions).thenReturn(listOf(expectedSession)) 258 // When 259 var actualResult = false 260 TestUtil.runOnExecutorSync(MODEL_EXECUTOR) { 261 actualResult = installSessionHelper.verifySessionInfo(expectedSession) 262 } 263 // Then 264 assertThat(actualResult).isTrue() 265 } 266 } 267