diff --git a/tests/multivalentTests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt b/tests/multivalentTests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt new file mode 100644 index 0000000000..3dd8dbceec --- /dev/null +++ b/tests/multivalentTests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.pm + +import android.content.pm.ApplicationInfo +import android.content.pm.ApplicationInfo.FLAG_INSTALLED +import android.content.pm.LauncherApps +import android.content.pm.PackageInstaller +import android.content.pm.PackageManager +import android.graphics.Bitmap +import android.os.UserHandle +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.launcher3.LauncherPrefs +import com.android.launcher3.LauncherPrefs.Companion.PROMISE_ICON_IDS +import com.android.launcher3.util.Executors.MODEL_EXECUTOR +import com.android.launcher3.util.IntArray +import com.android.launcher3.util.LauncherModelHelper +import com.android.launcher3.util.TestUtil +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.spy +import org.mockito.kotlin.whenever + +@SmallTest +@RunWith(AndroidJUnit4::class) +class InstallSessionHelperTest { + + private val launcherModelHelper = LauncherModelHelper() + private val sandboxContext = spy(launcherModelHelper.sandboxContext) + private val packageManager = sandboxContext.packageManager + private val expectedAppPackage = "expectedAppPackage" + private val expectedInstallerPackage = "expectedInstallerPackage" + private val mockPackageInstaller: PackageInstaller = mock() + + private lateinit var installSessionHelper: InstallSessionHelper + private lateinit var launcherApps: LauncherApps + + @Before + fun setup() { + whenever(packageManager.packageInstaller).thenReturn(mockPackageInstaller) + whenever(sandboxContext.packageName).thenReturn(expectedInstallerPackage) + launcherApps = sandboxContext.spyService(LauncherApps::class.java) + installSessionHelper = InstallSessionHelper(sandboxContext) + } + + @Test + fun `getActiveSessions fetches verified install sessions from LauncherApps`() { + // Given + val expectedVerifiedSession1 = + PackageInstaller.SessionInfo().apply { + sessionId = 0 + installerPackageName = expectedInstallerPackage + appPackageName = expectedAppPackage + userId = 0 + } + val expectedVerifiedSession2 = + PackageInstaller.SessionInfo().apply { + sessionId = 1 + installerPackageName = expectedInstallerPackage + appPackageName = "app2" + userId = 0 + } + val expectedSessions = listOf(expectedVerifiedSession1, expectedVerifiedSession2) + whenever(launcherApps.allPackageInstallerSessions).thenReturn(expectedSessions) + // When + val actualSessions = installSessionHelper.getActiveSessions() + // Then + assertThat(actualSessions.values.toList()).isEqualTo(expectedSessions) + } + + @Test + fun `getActiveSessionInfo fetches verified install sessions for given user and pkg`() { + // Given + val expectedVerifiedSession = + PackageInstaller.SessionInfo().apply { + installerPackageName = expectedInstallerPackage + appPackageName = expectedAppPackage + userId = 0 + } + whenever(launcherApps.allPackageInstallerSessions) + .thenReturn(listOf(expectedVerifiedSession)) + // When + val actualSession = + installSessionHelper.getActiveSessionInfo(UserHandle(0), expectedAppPackage) + // Then + assertThat(actualSession).isEqualTo(expectedVerifiedSession) + } + + @Test + fun `getVerifiedSessionInfo verifies and returns session for given id`() { + // Given + val expectedSession = + PackageInstaller.SessionInfo().apply { + sessionId = 1 + installerPackageName = expectedInstallerPackage + appPackageName = expectedAppPackage + userId = 0 + } + whenever(mockPackageInstaller.getSessionInfo(1)).thenReturn(expectedSession) + // When + val actualSession = installSessionHelper.getVerifiedSessionInfo(1) + // Then + assertThat(actualSession).isEqualTo(expectedSession) + } + + @Test + fun `isTrustedPackage returns true if LauncherApps finds ApplicationInfo`() { + // Given + val expectedApplicationInfo = + ApplicationInfo().apply { + flags = flags or FLAG_INSTALLED + enabled = true + } + doReturn(expectedApplicationInfo) + .whenever(launcherApps) + .getApplicationInfo(expectedAppPackage, ApplicationInfo.FLAG_SYSTEM, UserHandle(0)) + // When + val actualResult = installSessionHelper.isTrustedPackage(expectedAppPackage, UserHandle(0)) + // Then + assertThat(actualResult).isTrue() + } + + @Test + fun `getAllVerifiedSessions verifies and returns all active install sessions`() { + // Given + val expectedVerifiedSession1 = + PackageInstaller.SessionInfo().apply { + sessionId = 0 + installerPackageName = expectedInstallerPackage + appPackageName = expectedAppPackage + userId = 0 + } + val expectedVerifiedSession2 = + PackageInstaller.SessionInfo().apply { + sessionId = 1 + installerPackageName = expectedInstallerPackage + appPackageName = "app2" + userId = 0 + } + val expectedSessions = listOf(expectedVerifiedSession1, expectedVerifiedSession2) + whenever(launcherApps.allPackageInstallerSessions).thenReturn(expectedSessions) + // When + val actualSessions = installSessionHelper.allVerifiedSessions + // Then + assertThat(actualSessions).isEqualTo(expectedSessions) + } + + @Test + fun `promiseIconAddedForId returns true if there is a promiseIcon with the session id`() { + // Given + val expectedIdString = IntArray().apply { add(1) }.toConcatString() + LauncherPrefs.get(sandboxContext).putSync(Pair(PROMISE_ICON_IDS, expectedIdString)) + val expectedSession = + PackageInstaller.SessionInfo().apply { + sessionId = 1 + installerPackageName = expectedInstallerPackage + appPackageName = "app2" + userId = 0 + } + whenever(launcherApps.allPackageInstallerSessions).thenReturn(listOf(expectedSession)) + // When + var actualResult = false + TestUtil.runOnExecutorSync(MODEL_EXECUTOR) { + actualResult = installSessionHelper.promiseIconAddedForId(1) + } + // Then + assertThat(actualResult).isTrue() + } + + @Test + fun `removePromiseIconId removes promiseIconId for given Session id`() { + // Given + val expectedIdString = IntArray().apply { add(1) }.toConcatString() + LauncherPrefs.get(sandboxContext).putSync(Pair(PROMISE_ICON_IDS, expectedIdString)) + val expectedSession = + PackageInstaller.SessionInfo().apply { + sessionId = 1 + installerPackageName = expectedInstallerPackage + appPackageName = "app2" + userId = 0 + } + whenever(launcherApps.allPackageInstallerSessions).thenReturn(listOf(expectedSession)) + // When + var actualResult = true + TestUtil.runOnExecutorSync(MODEL_EXECUTOR) { + installSessionHelper.removePromiseIconId(1) + actualResult = installSessionHelper.promiseIconAddedForId(1) + } + // Then + assertThat(actualResult).isFalse() + } + + @Test + fun `tryQueuePromiseAppIcon will update promise icon ids from eligible sessions`() { + // Given + val expectedIdString = IntArray().apply { add(1) }.toConcatString() + LauncherPrefs.get(sandboxContext).putSync(Pair(PROMISE_ICON_IDS, expectedIdString)) + val expectedSession = + PackageInstaller.SessionInfo().apply { + sessionId = 1 + installerPackageName = expectedInstallerPackage + appPackageName = "appPackage" + userId = 0 + appIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8) + appLabel = "appLabel" + installReason = PackageManager.INSTALL_REASON_USER + } + whenever(launcherApps.allPackageInstallerSessions).thenReturn(listOf(expectedSession)) + // When + var wasPromiseIconAdded = false + var actualPromiseIconIds = "" + TestUtil.runOnExecutorSync(MODEL_EXECUTOR) { + installSessionHelper.removePromiseIconId(1) + installSessionHelper.tryQueuePromiseAppIcon(expectedSession) + wasPromiseIconAdded = installSessionHelper.promiseIconAddedForId(1) + actualPromiseIconIds = LauncherPrefs.get(sandboxContext).get(PROMISE_ICON_IDS) + } + // Then + assertThat(wasPromiseIconAdded).isTrue() + assertThat(actualPromiseIconIds).isEqualTo(expectedIdString) + } + + @Test + fun `verifySessionInfo is true if can verify given SessionInfo`() { + // Given + val expectedIdString = IntArray().apply { add(1) }.toConcatString() + LauncherPrefs.get(sandboxContext).putSync(Pair(PROMISE_ICON_IDS, expectedIdString)) + val expectedSession = + PackageInstaller.SessionInfo().apply { + sessionId = 1 + installerPackageName = expectedInstallerPackage + appPackageName = "appPackage" + userId = 0 + appIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8) + appLabel = "appLabel" + installReason = PackageManager.INSTALL_REASON_USER + } + whenever(launcherApps.allPackageInstallerSessions).thenReturn(listOf(expectedSession)) + // When + var actualResult = false + TestUtil.runOnExecutorSync(MODEL_EXECUTOR) { + actualResult = installSessionHelper.verifySessionInfo(expectedSession) + } + // Then + assertThat(actualResult).isTrue() + } +}