Fix b/265632782: Battery usage app list changed when entering the app details page and back

This only happens on the first time the Settings package is installed.
Discussed with Chaohui, the old showSystemApp() logic in Settings->Apps has some issues. This cl updates the logic to the new logic Chaohui provided.

Bug: 265632782
Fix: 265632782
Test: manual
Change-Id: Iff5838f0299aed1b0ba2164b97e7fbdeefcadbee
This commit is contained in:
Zaiyue Xue
2023-01-16 16:49:21 +08:00
parent c5fa04ec36
commit 91f7ae3dc0
3 changed files with 73 additions and 20 deletions

View File

@@ -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,

View File

@@ -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

View File

@@ -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 {