Merge "Fix b/265632782: Battery usage app list changed when entering the app details page and back"
This commit is contained in:
committed by
Android (Google) Code Review
commit
292b8f112e
@@ -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<Int>,
|
||||
showSystemFlow: Flow<Boolean>,
|
||||
): Flow<(app: ApplicationInfo) -> Boolean>
|
||||
|
||||
/** Gets the system app package names. */
|
||||
fun getSystemPackageNamesBlocking(config: AppListConfig): Set<String>
|
||||
}
|
||||
|
||||
/**
|
||||
* Util for app list repository.
|
||||
*/
|
||||
object AppListRepositoryUtil {
|
||||
/** Gets the system app package names. */
|
||||
@JvmStatic
|
||||
fun getSystemPackageNames(context: Context, config: AppListConfig): Set<String> {
|
||||
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<String> =
|
||||
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<String> {
|
||||
@@ -117,6 +142,11 @@ internal class AppListRepositoryImpl(private val context: Context) : AppListRepo
|
||||
}
|
||||
}
|
||||
|
||||
private fun isSystemApp(app: ApplicationInfo, homeOrLauncherPackages: Set<String>): Boolean {
|
||||
return !app.isUpdatedSystemApp && app.isSystemApp &&
|
||||
!(app.packageName in homeOrLauncherPackages)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun ApplicationInfo.isInAppList(
|
||||
showInstantApps: Boolean,
|
||||
|
||||
@@ -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<ResolveInfo>
|
||||
@@ -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<ResolveInfoFlags>(), 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
|
||||
|
||||
@@ -90,6 +90,8 @@ class AppListViewModelTest {
|
||||
userIdFlow: Flow<Int>,
|
||||
showSystemFlow: Flow<Boolean>,
|
||||
): Flow<(app: ApplicationInfo) -> Boolean> = flowOf { true }
|
||||
|
||||
override fun getSystemPackageNamesBlocking(config: AppListConfig): Set<String> = setOf()
|
||||
}
|
||||
|
||||
private object FakeAppRepository : AppRepository {
|
||||
|
||||
Reference in New Issue
Block a user