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

Commit c71f8ae4 authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Add AppListRepository.loadAndFilterApps()

To load all non system apps with shared app list filter logic.

Bug: 280280596
Test: Unit test
Change-Id: I5158d3a838bd51b073329bfe14a2246e2e1e4c2c
parent f6966492
Loading
Loading
Loading
Loading
+17 −14
Original line number Original line Diff line number Diff line
@@ -34,11 +34,11 @@ import kotlinx.coroutines.runBlocking
/**
/**
 * The repository to load the App List data.
 * The repository to load the App List data.
 */
 */
internal interface AppListRepository {
interface AppListRepository {
    /** Loads the list of [ApplicationInfo]. */
    /** Loads the list of [ApplicationInfo]. */
    suspend fun loadApps(
    suspend fun loadApps(
        userId: Int,
        userId: Int,
        showInstantApps: Boolean = false,
        loadInstantApps: Boolean = false,
        matchAnyUserForAdmin: Boolean = false,
        matchAnyUserForAdmin: Boolean = false,
    ): List<ApplicationInfo>
    ): List<ApplicationInfo>


@@ -50,6 +50,9 @@ internal interface AppListRepository {


    /** Gets the system app package names. */
    /** Gets the system app package names. */
    fun getSystemPackageNamesBlocking(userId: Int): Set<String>
    fun getSystemPackageNamesBlocking(userId: Int): Set<String>

    /** Loads the list of [ApplicationInfo], and filter base on `isSystemApp`. */
    suspend fun loadAndFilterApps(userId: Int, isSystemApp: Boolean): List<ApplicationInfo>
}
}


/**
/**
@@ -62,13 +65,13 @@ object AppListRepositoryUtil {
        AppListRepositoryImpl(context).getSystemPackageNamesBlocking(userId)
        AppListRepositoryImpl(context).getSystemPackageNamesBlocking(userId)
}
}


internal class AppListRepositoryImpl(private val context: Context) : AppListRepository {
class AppListRepositoryImpl(private val context: Context) : AppListRepository {
    private val packageManager = context.packageManager
    private val packageManager = context.packageManager
    private val userManager = context.userManager
    private val userManager = context.userManager


    override suspend fun loadApps(
    override suspend fun loadApps(
        userId: Int,
        userId: Int,
        showInstantApps: Boolean,
        loadInstantApps: Boolean,
        matchAnyUserForAdmin: Boolean,
        matchAnyUserForAdmin: Boolean,
    ): List<ApplicationInfo> = coroutineScope {
    ): List<ApplicationInfo> = coroutineScope {
        val hiddenSystemModulesDeferred = async {
        val hiddenSystemModulesDeferred = async {
@@ -86,7 +89,7 @@ internal class AppListRepositoryImpl(private val context: Context) : AppListRepo
        val hiddenSystemModules = hiddenSystemModulesDeferred.await()
        val hiddenSystemModules = hiddenSystemModulesDeferred.await()
        val hideWhenDisabledPackages = hideWhenDisabledPackagesDeferred.await()
        val hideWhenDisabledPackages = hideWhenDisabledPackagesDeferred.await()
        installedApplicationsAsUser.filter { app ->
        installedApplicationsAsUser.filter { app ->
            app.isInAppList(showInstantApps, hiddenSystemModules, hideWhenDisabledPackages)
            app.isInAppList(loadInstantApps, hiddenSystemModules, hideWhenDisabledPackages)
        }
        }
    }
    }


@@ -136,16 +139,16 @@ internal class AppListRepositoryImpl(private val context: Context) : AppListRepo
    ): Flow<(app: ApplicationInfo) -> Boolean> =
    ): Flow<(app: ApplicationInfo) -> Boolean> =
        userIdFlow.combine(showSystemFlow, ::showSystemPredicate)
        userIdFlow.combine(showSystemFlow, ::showSystemPredicate)


    override fun getSystemPackageNamesBlocking(userId: Int) =
    override fun getSystemPackageNamesBlocking(userId: Int) = runBlocking {
        runBlocking { getSystemPackageNames(userId) }
        loadAndFilterApps(userId = userId, isSystemApp = true).map { it.packageName }.toSet()
    }


    private suspend fun getSystemPackageNames(userId: Int): Set<String> =
    override suspend fun loadAndFilterApps(userId: Int, isSystemApp: Boolean) = coroutineScope {
        coroutineScope {
        val loadAppsDeferred = async { loadApps(userId) }
        val loadAppsDeferred = async { loadApps(userId) }
        val homeOrLauncherPackages = loadHomeOrLauncherPackages(userId)
        val homeOrLauncherPackages = loadHomeOrLauncherPackages(userId)
            val showSystemPredicate =
        loadAppsDeferred.await().filter { app ->
                { app: ApplicationInfo -> isSystemApp(app, homeOrLauncherPackages) }
            isSystemApp(app, homeOrLauncherPackages) == isSystemApp
            loadAppsDeferred.await().filter(showSystemPredicate).map { it.packageName }.toSet()
        }
    }
    }


    private suspend fun showSystemPredicate(
    private suspend fun showSystemPredicate(
+17 −2
Original line number Original line Diff line number Diff line
@@ -108,7 +108,7 @@ class AppListRepositoryTest {


        val appList = repository.loadApps(
        val appList = repository.loadApps(
            userId = ADMIN_USER_ID,
            userId = ADMIN_USER_ID,
            showInstantApps = false,
            loadInstantApps = false,
        )
        )


        assertThat(appList).containsExactly(NORMAL_APP)
        assertThat(appList).containsExactly(NORMAL_APP)
@@ -120,7 +120,7 @@ class AppListRepositoryTest {


        val appList = repository.loadApps(
        val appList = repository.loadApps(
            userId = ADMIN_USER_ID,
            userId = ADMIN_USER_ID,
            showInstantApps = true,
            loadInstantApps = true,
        )
        )


        assertThat(appList).containsExactly(NORMAL_APP, INSTANT_APP)
        assertThat(appList).containsExactly(NORMAL_APP, INSTANT_APP)
@@ -325,6 +325,21 @@ class AppListRepositoryTest {
        assertThat(systemPackageNames).containsExactly(SYSTEM_APP.packageName)
        assertThat(systemPackageNames).containsExactly(SYSTEM_APP.packageName)
    }
    }


    @Test
    fun loadAndFilterApps_loadNonSystemApp_returnExpectedValues() = runTest {
        mockInstalledApplications(
            apps = listOf(
                NORMAL_APP, INSTANT_APP, SYSTEM_APP, UPDATED_SYSTEM_APP, HOME_APP, IN_LAUNCHER_APP
            ),
            userId = ADMIN_USER_ID,
        )

        val appList = repository.loadAndFilterApps(userId = ADMIN_USER_ID, isSystemApp = false)

        assertThat(appList)
            .containsExactly(NORMAL_APP, UPDATED_SYSTEM_APP, HOME_APP, IN_LAUNCHER_APP)
    }

    private suspend fun getShowSystemPredicate(showSystem: Boolean) =
    private suspend fun getShowSystemPredicate(showSystem: Boolean) =
        repository.showSystemPredicate(
        repository.showSystemPredicate(
            userIdFlow = flowOf(ADMIN_USER_ID),
            userIdFlow = flowOf(ADMIN_USER_ID),
+4 −1
Original line number Original line Diff line number Diff line
@@ -87,7 +87,7 @@ class AppListViewModelTest {
    private object FakeAppListRepository : AppListRepository {
    private object FakeAppListRepository : AppListRepository {
        override suspend fun loadApps(
        override suspend fun loadApps(
            userId: Int,
            userId: Int,
            showInstantApps: Boolean,
            loadInstantApps: Boolean,
            matchAnyUserForAdmin: Boolean,
            matchAnyUserForAdmin: Boolean,
        ) = listOf(APP)
        ) = listOf(APP)


@@ -97,6 +97,9 @@ class AppListViewModelTest {
        ): Flow<(app: ApplicationInfo) -> Boolean> = flowOf { true }
        ): Flow<(app: ApplicationInfo) -> Boolean> = flowOf { true }


        override fun getSystemPackageNamesBlocking(userId: Int): Set<String> = emptySet()
        override fun getSystemPackageNamesBlocking(userId: Int): Set<String> = emptySet()

        override suspend fun loadAndFilterApps(userId: Int, isSystemApp: Boolean) =
            emptyList<ApplicationInfo>()
    }
    }


    private object FakeAppRepository : AppRepository {
    private object FakeAppRepository : AppRepository {