diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt index cbb4fbe32713b..ce0c5511c3d0e 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt @@ -26,6 +26,7 @@ import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.runBlocking /** * The config used to load the App List. @@ -47,8 +48,21 @@ internal interface AppListRepository { userIdFlow: Flow, showSystemFlow: Flow, ): Flow<(app: ApplicationInfo) -> Boolean> + + /** Gets the system app package names. */ + fun getSystemPackageNamesBlocking(config: AppListConfig): Set } +/** + * Util for app list repository. + */ +object AppListRepositoryUtil { + /** Gets the system app package names. */ + @JvmStatic + fun getSystemPackageNames(context: Context, config: AppListConfig): Set { + return AppListRepositoryImpl(context).getSystemPackageNamesBlocking(config) + } +} internal class AppListRepositoryImpl(private val context: Context) : AppListRepository { private val packageManager = context.packageManager @@ -83,15 +97,26 @@ internal class AppListRepositoryImpl(private val context: Context) : AppListRepo ): Flow<(app: ApplicationInfo) -> Boolean> = userIdFlow.combine(showSystemFlow, ::showSystemPredicate) + override fun getSystemPackageNamesBlocking(config: AppListConfig) = runBlocking { + getSystemPackageNames(config) + } + + private suspend fun getSystemPackageNames(config: AppListConfig): Set = + coroutineScope { + val loadAppsDeferred = async { loadApps(config) } + val homeOrLauncherPackages = loadHomeOrLauncherPackages(config.userId) + val showSystemPredicate = + { app: ApplicationInfo -> isSystemApp(app, homeOrLauncherPackages) } + loadAppsDeferred.await().filter(showSystemPredicate).map { it.packageName }.toSet() + } + private suspend fun showSystemPredicate( userId: Int, showSystem: Boolean, ): (app: ApplicationInfo) -> Boolean { if (showSystem) return { true } val homeOrLauncherPackages = loadHomeOrLauncherPackages(userId) - return { app -> - app.isUpdatedSystemApp || !app.isSystemApp || app.packageName in homeOrLauncherPackages - } + return { app -> !isSystemApp(app, homeOrLauncherPackages) } } private suspend fun loadHomeOrLauncherPackages(userId: Int): Set { @@ -117,6 +142,11 @@ internal class AppListRepositoryImpl(private val context: Context) : AppListRepo } } + private fun isSystemApp(app: ApplicationInfo, homeOrLauncherPackages: Set): Boolean { + return !app.isUpdatedSystemApp && app.isSystemApp && + !(app.packageName in homeOrLauncherPackages) + } + companion object { private fun ApplicationInfo.isInAppList( showInstantApps: Boolean, diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt index 2d8f0098480cf..b0ea40a49a0ee 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt @@ -180,9 +180,7 @@ class AppListRepositoryTest { @Test fun showSystemPredicate_showSystem() = runTest { - val app = ApplicationInfo().apply { - flags = ApplicationInfo.FLAG_SYSTEM - } + val app = SYSTEM_APP val showSystemPredicate = getShowSystemPredicate(showSystem = true) @@ -191,9 +189,7 @@ class AppListRepositoryTest { @Test fun showSystemPredicate_notShowSystemAndIsSystemApp() = runTest { - val app = ApplicationInfo().apply { - flags = ApplicationInfo.FLAG_SYSTEM - } + val app = SYSTEM_APP val showSystemPredicate = getShowSystemPredicate(showSystem = false) @@ -202,9 +198,7 @@ class AppListRepositoryTest { @Test fun showSystemPredicate_isUpdatedSystemApp() = runTest { - val app = ApplicationInfo().apply { - flags = ApplicationInfo.FLAG_SYSTEM or ApplicationInfo.FLAG_UPDATED_SYSTEM_APP - } + val app = UPDATED_SYSTEM_APP val showSystemPredicate = getShowSystemPredicate(showSystem = false) @@ -213,10 +207,8 @@ class AppListRepositoryTest { @Test fun showSystemPredicate_isHome() = runTest { - val app = ApplicationInfo().apply { - flags = ApplicationInfo.FLAG_SYSTEM - packageName = "home.app" - } + val app = HOME_APP + whenever(packageManager.getHomeActivities(any())).thenAnswer { @Suppress("UNCHECKED_CAST") val resolveInfos = it.arguments[0] as MutableList @@ -231,10 +223,8 @@ class AppListRepositoryTest { @Test fun showSystemPredicate_appInLauncher() = runTest { - val app = ApplicationInfo().apply { - flags = ApplicationInfo.FLAG_SYSTEM - packageName = "app.in.launcher" - } + val app = IN_LAUMCHER_APP + whenever( packageManager.queryIntentActivitiesAsUser(any(), any(), eq(USER_ID)) ).thenReturn(listOf(resolveInfoOf(packageName = app.packageName))) @@ -244,6 +234,17 @@ class AppListRepositoryTest { assertThat(showSystemPredicate(app)).isTrue() } + @Test + fun getSystemPackageNames_returnExpectedValues() = runTest { + mockInstalledApplications(listOf( + NORMAL_APP, INSTANT_APP, SYSTEM_APP, UPDATED_SYSTEM_APP, HOME_APP, IN_LAUMCHER_APP)) + val appListConfig = AppListConfig(userId = USER_ID, showInstantApps = false) + + val systemPackageNames = AppListRepositoryUtil.getSystemPackageNames(context, appListConfig) + + assertThat(systemPackageNames).containsExactly("system.app", "home.app", "app.in.launcher") + } + private suspend fun getShowSystemPredicate(showSystem: Boolean) = repository.showSystemPredicate( userIdFlow = flowOf(USER_ID), @@ -264,6 +265,26 @@ class AppListRepositoryTest { privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT } + val SYSTEM_APP = ApplicationInfo().apply { + packageName = "system.app" + flags = ApplicationInfo.FLAG_SYSTEM + } + + val UPDATED_SYSTEM_APP = ApplicationInfo().apply { + packageName = "updated.system.app" + flags = ApplicationInfo.FLAG_SYSTEM or ApplicationInfo.FLAG_UPDATED_SYSTEM_APP + } + + val HOME_APP = ApplicationInfo().apply { + packageName = "home.app" + flags = ApplicationInfo.FLAG_SYSTEM + } + + val IN_LAUMCHER_APP = ApplicationInfo().apply { + packageName = "app.in.launcher" + flags = ApplicationInfo.FLAG_SYSTEM + } + fun resolveInfoOf(packageName: String) = ResolveInfo().apply { activityInfo = ActivityInfo().apply { this.packageName = packageName diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt index f51448744c56a..7151439c2a2ff 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt @@ -90,6 +90,8 @@ class AppListViewModelTest { userIdFlow: Flow, showSystemFlow: Flow, ): Flow<(app: ApplicationInfo) -> Boolean> = flowOf { true } + + override fun getSystemPackageNamesBlocking(config: AppListConfig): Set = setOf() } private object FakeAppRepository : AppRepository {