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