From 528c716182b7a953bd34f1cb44a5b278586ab6a6 Mon Sep 17 00:00:00 2001 From: Charlie Anderson Date: Fri, 19 Jul 2024 16:38:41 -0400 Subject: [PATCH] [Test Week] add unit tests for InstallSessionTracker 6 public methods tested, 8 unit tests total no previous test class Bug: 353303621 Test: unit tests Flag: TEST_ONLY Change-Id: Ie2b5c88566c1a512e534654ccc7db1ec6b277a83 --- .../launcher3/pm/InstallSessionTracker.java | 1 - .../launcher3/pm/InstallSessionTrackerTest.kt | 228 ++++++++++++++++++ 2 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 tests/src/com/android/launcher3/pm/InstallSessionTrackerTest.kt diff --git a/src/com/android/launcher3/pm/InstallSessionTracker.java b/src/com/android/launcher3/pm/InstallSessionTracker.java index 24d58f3e98..c117be4601 100644 --- a/src/com/android/launcher3/pm/InstallSessionTracker.java +++ b/src/com/android/launcher3/pm/InstallSessionTracker.java @@ -32,7 +32,6 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import com.android.launcher3.Flags; -import com.android.launcher3.Utilities; import com.android.launcher3.util.PackageUserKey; import java.lang.ref.WeakReference; diff --git a/tests/src/com/android/launcher3/pm/InstallSessionTrackerTest.kt b/tests/src/com/android/launcher3/pm/InstallSessionTrackerTest.kt new file mode 100644 index 0000000000..b531adb7af --- /dev/null +++ b/tests/src/com/android/launcher3/pm/InstallSessionTrackerTest.kt @@ -0,0 +1,228 @@ +/* + * 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.LauncherApps +import android.content.pm.PackageInstaller +import android.os.Build +import android.os.UserHandle +import android.platform.test.annotations.EnableFlags +import android.platform.test.flag.junit.SetFlagsRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SdkSuppress +import androidx.test.filters.SmallTest +import com.android.launcher3.Flags.FLAG_ENABLE_SUPPORT_FOR_ARCHIVING +import com.android.launcher3.util.Executors.MODEL_EXECUTOR +import com.android.launcher3.util.LauncherModelHelper +import com.android.launcher3.util.PackageUserKey +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.any +import org.mockito.kotlin.mock +import org.mockito.kotlin.spy +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +@SmallTest +@RunWith(AndroidJUnit4::class) +class InstallSessionTrackerTest { + @get:Rule val setFlagsRule = SetFlagsRule() + + private val mockInstallSessionHelper: InstallSessionHelper = mock() + private val mockCallback: InstallSessionTracker.Callback = mock() + private val mockPackageInstaller: PackageInstaller = mock() + + private val launcherModelHelper = LauncherModelHelper() + private val sandboxContext = launcherModelHelper.sandboxContext + + lateinit var launcherApps: LauncherApps + lateinit var installSessionTracker: InstallSessionTracker + + @Before + fun setup() { + launcherApps = sandboxContext.spyService(LauncherApps::class.java) + installSessionTracker = + InstallSessionTracker( + mockInstallSessionHelper, + mockCallback, + mockPackageInstaller, + launcherApps + ) + } + + @After + fun teardown() { + launcherModelHelper.destroy() + } + + @Test + fun `onCreated triggers callbacks for setting up new install session`() { + // Given + val expectedSessionId = 1 + val expectedSession = + PackageInstaller.SessionInfo().apply { + sessionId = expectedSessionId + appPackageName = "appPackageName" + userId = 0 + } + val expectedPackageKey = PackageUserKey("appPackageName", UserHandle(0)) + whenever(mockInstallSessionHelper.getVerifiedSessionInfo(expectedSessionId)) + .thenReturn(expectedSession) + // When + installSessionTracker.onCreated(expectedSessionId) + // Then + verify(mockCallback).onInstallSessionCreated(any()) + verify(mockCallback).onUpdateSessionDisplay(expectedPackageKey, expectedSession) + verify(mockInstallSessionHelper).tryQueuePromiseAppIcon(expectedSession) + } + + @Test + @EnableFlags(FLAG_ENABLE_SUPPORT_FOR_ARCHIVING) + fun `onCreated for unarchival triggers onPackageStateChanged`() { + // Given + val expectedSessionId = 1 + val expectedSession = + spy(PackageInstaller.SessionInfo()).apply { + sessionId = expectedSessionId + appPackageName = "appPackageName" + userId = 0 + whenever(isUnarchival).thenReturn(true) + } + whenever(mockInstallSessionHelper.getVerifiedSessionInfo(expectedSessionId)) + .thenReturn(expectedSession) + // When + installSessionTracker.onCreated(expectedSessionId) + // Then + verify(mockCallback).onPackageStateChanged(any()) + } + + @Test + fun `onFinished triggers onPackageStateChanged if session found in cache`() { + // Given + val expectedSessionId = 1 + val expectedSession = + PackageInstaller.SessionInfo().apply { + sessionId = expectedSessionId + appPackageName = "appPackageName" + userId = 0 + } + val expectedPackageKey = PackageUserKey("appPackageName", UserHandle(0)) + whenever(mockInstallSessionHelper.getVerifiedSessionInfo(expectedSessionId)) + .thenReturn(expectedSession) + whenever(mockInstallSessionHelper.activeSessions) + .thenReturn(hashMapOf(expectedPackageKey to expectedSession)) + // When + installSessionTracker.onFinished(expectedSessionId, /* success */ true) + // Then + verify(mockCallback).onPackageStateChanged(any()) + } + + @Test + fun `onFinished failure calls onSessionFailure and promise icon removal for existing icon`() { + // Given + val expectedSessionId = 1 + val expectedPackage = "appPackageName" + val expectedSession = + PackageInstaller.SessionInfo().apply { + sessionId = expectedSessionId + appPackageName = expectedPackage + userId = 0 + } + val expectedPackageKey = PackageUserKey(expectedPackage, UserHandle(0)) + whenever(mockInstallSessionHelper.getVerifiedSessionInfo(expectedSessionId)) + .thenReturn(expectedSession) + whenever(mockInstallSessionHelper.activeSessions) + .thenReturn(hashMapOf(expectedPackageKey to expectedSession)) + whenever(mockInstallSessionHelper.promiseIconAddedForId(expectedSessionId)).thenReturn(true) + // When + installSessionTracker.onFinished(expectedSessionId, /* success */ false) + // Then + verify(mockCallback).onSessionFailure(expectedPackage, expectedPackageKey.mUser) + verify(mockInstallSessionHelper).removePromiseIconId(expectedSessionId) + } + + @Test + fun `onProgressChanged triggers onPackageStateChanged if verified session found`() { + // Given + val expectedSessionId = 1 + val expectedSession = + PackageInstaller.SessionInfo().apply { + sessionId = expectedSessionId + appPackageName = "appPackageName" + userId = 0 + } + whenever(mockInstallSessionHelper.getVerifiedSessionInfo(expectedSessionId)) + .thenReturn(expectedSession) + // When + installSessionTracker.onProgressChanged(expectedSessionId, /* progress */ 50f) + // Then + verify(mockCallback).onPackageStateChanged(any()) + } + + @Test + fun `onBadgingChanged triggers session display update and queues promise icon if verified`() { + // Given + val expectedSessionId = 1 + val expectedSession = + PackageInstaller.SessionInfo().apply { + sessionId = expectedSessionId + appPackageName = "appPackageName" + userId = 0 + } + val expectedPackageKey = PackageUserKey("appPackageName", UserHandle(0)) + whenever(mockInstallSessionHelper.getVerifiedSessionInfo(expectedSessionId)) + .thenReturn(expectedSession) + // When + installSessionTracker.onBadgingChanged(expectedSessionId) + // Then + verify(mockCallback).onUpdateSessionDisplay(expectedPackageKey, expectedSession) + verify(mockInstallSessionHelper).tryQueuePromiseAppIcon(expectedSession) + } + + @Test + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q) + fun `register triggers registerPackageInstallerSessionCallback for versions from Q`() { + // Given + whenever( + launcherApps.registerPackageInstallerSessionCallback( + MODEL_EXECUTOR, + installSessionTracker + ) + ) + .then { /* no-op */ } + // When + installSessionTracker.register() + // Then + verify(launcherApps) + .registerPackageInstallerSessionCallback(MODEL_EXECUTOR, installSessionTracker) + } + + @Test + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q) + fun `unregister triggers unregisterPackageInstallerSessionCallback for versions from Q`() { + // Given + whenever(launcherApps.unregisterPackageInstallerSessionCallback(installSessionTracker)) + .then { /* no-op */ } + // When + installSessionTracker.unregister() + // Then + verify(launcherApps).unregisterPackageInstallerSessionCallback(installSessionTracker) + } +}