Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 292b8f11 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents db87c407 91f7ae3d
Loading
Loading
Loading
Loading
+33 −3
Original line number Diff line number Diff line
@@ -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,
+38 −17
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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 {