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

Commit 5e4d333e authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Create TogglePermissionAppListPage

Install unknown apps can be one of the use case.

Bug: 235727273
Test: Manual with Test App
Change-Id: I50bb43dbca756972d5fc4076129f3b84c23eeacd
parent 9c37c6bb
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -21,4 +21,8 @@
    <string name="menu_show_system">Show system</string>
    <!-- [CHAR LIMIT=NONE] Menu for manage apps to control whether system processes are hidden -->
    <string name="menu_hide_system">Hide system</string>
    <!-- Preference summary text for an app when it is allowed for a permission. [CHAR LIMIT=45] -->
    <string name="app_permission_summary_allowed">Allowed</string>
    <!-- Preference summary text for an app when it is disallowed for a permission. [CHAR LIMIT=45] -->
    <string name="app_permission_summary_not_allowed">Not allowed</string>
</resources>
+4 −1
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@ package com.android.settingslib.spaprivileged.model.app

import android.content.pm.ApplicationInfo
import android.icu.text.CollationKey
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import kotlinx.coroutines.flow.Flow

data class AppEntry<T : AppRecord>(
@@ -22,5 +24,6 @@ interface AppListModel<T : AppRecord> {
        { it.record.app.uid },
    )

    fun getSummary(option: Int, record: T): Flow<String>?
    @Composable
    fun getSummary(option: Int, record: T): State<String>?
}
+1 −10
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ private fun <T : AppRecord> AppListWidget(
        ) {
            items(count = list.size, key = { option to list[it].record.app.packageName }) {
                val appEntry = list[it]
                val summary = getSummary(listModel, option, appEntry.record)
                val summary = listModel.getSummary(option, appEntry.record) ?: "".toState()
                val itemModel = remember(appEntry) {
                    AppListItemModel(appEntry.record, appEntry.label, summary)
                }
@@ -100,12 +100,3 @@ private fun <T : AppRecord> loadAppEntries(

    return viewModel.appListDataFlow.collectAsState(null, Dispatchers.Default)
}

@Composable
private fun <T : AppRecord> getSummary(
    listModel: AppListModel<T>,
    option: Int,
    record: T,
): State<String> = remember(option) { listModel.getSummary(option, record) }
    ?.collectAsState(stringResource(R.string.summary_placeholder), Dispatchers.Default)
    ?: "".toState()
+11 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.settingslib.spaprivileged.template.app

import android.content.Context
import android.content.pm.ApplicationInfo
import android.os.Bundle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -28,21 +29,24 @@ import androidx.compose.ui.res.stringResource
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.android.settingslib.spa.framework.api.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.rememberContext
import com.android.settingslib.spa.widget.preference.SwitchPreference
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import com.android.settingslib.spaprivileged.model.app.AppRecord
import com.android.settingslib.spaprivileged.model.app.PackageManagers
import com.android.settingslib.spaprivileged.model.app.toRoute
import kotlinx.coroutines.Dispatchers

private const val NAME = "TogglePermissionAppInfoPage"
private const val PERMISSION = "permission"
private const val PACKAGE_NAME = "packageName"
private const val USER_ID = "userId"

open class TogglePermissionAppInfoPageProvider(
internal class TogglePermissionAppInfoPageProvider(
    private val factory: TogglePermissionAppListModelFactory,
) : SettingsPageProvider {
    override val name = "TogglePermissionAppInfoPage"
    override val name = NAME

    override val arguments = listOf(
        navArgument(PERMISSION) { type = NavType.StringType },
@@ -60,8 +64,11 @@ open class TogglePermissionAppInfoPageProvider(
        TogglePermissionAppInfoPage(listModel, packageName, userId)
    }

    fun getRoute(permissionType: String, packageName: String, userId: Int): String =
        "$name/$permissionType/$packageName/$userId"
    companion object {
        @Composable
        internal fun navigator(permissionType: String, app: ApplicationInfo) =
            navigator(route = "$NAME/$permissionType/${app.toRoute()}")
    }
}

@Composable
+31 −0
Original line number Diff line number Diff line
@@ -20,14 +20,25 @@ import android.content.Context
import android.content.pm.ApplicationInfo
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.res.stringResource
import com.android.settingslib.spa.framework.api.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.rememberContext
import com.android.settingslib.spa.framework.util.asyncMapItem
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.model.app.AppRecord
import kotlinx.coroutines.flow.Flow

interface TogglePermissionAppListModel<T : AppRecord> {
    val pageTitleResId: Int
    val switchTitleResId: Int
    val footerResId: Int

    fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>): Flow<List<T>> =
        appListFlow.asyncMapItem(::transformItem)

    fun transformItem(app: ApplicationInfo): T
    fun filter(userIdFlow: Flow<Int>, recordListFlow: Flow<List<T>>): Flow<List<T>>

    @Composable
    fun isAllowed(record: T): State<Boolean?>
@@ -41,4 +52,24 @@ interface TogglePermissionAppListModelFactory {
        permission: String,
        context: Context,
    ): TogglePermissionAppListModel<out AppRecord>

    fun createPageProviders(): List<SettingsPageProvider> = listOf(
        TogglePermissionAppListPageProvider(this),
        TogglePermissionAppInfoPageProvider(this),
    )

    @Composable
    fun EntryItem(permissionType: String) {
        val listModel = rememberModel(permissionType)
        Preference(
            object : PreferenceModel {
                override val title = stringResource(listModel.pageTitleResId)
                override val onClick = TogglePermissionAppListPageProvider.navigator(permissionType)
            }
        )
    }
}

@Composable
internal fun TogglePermissionAppListModelFactory.rememberModel(permission: String) =
    rememberContext { context -> createModel(permission, context) }
Loading