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

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

Add entry item for TogglePermissionAppInfoPage

To support adding items like "Install unknown apps" to App Settings
page.

Item will only displayed it's changeable for that app.

Bug: 236346018
Test: Manual with Settings App
Change-Id: Icf68e0eab0daf056ab1c30c8cebd4784aeb6a3a9
parent 274e5160
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<resources>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- [CHAR LIMIT=25] Text shown when there are no applications to display. -->
    <string name="no_applications">No apps.</string>
    <!-- [CHAR LIMIT=NONE] Menu for manage apps to control whether system processes are shown -->
@@ -25,4 +25,6 @@
    <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>
    <!-- Manage applications, version string displayed in app snippet -->
    <string name="version_text">version <xliff:g id="version_num">%1$s</xliff:g></string>
</resources>
+40 −27
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.settingslib.spaprivileged.template.app

import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.text.BidiFormatter
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -25,21 +27,23 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Divider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.android.settingslib.spa.framework.compose.rememberDrawablePainter
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.widget.ui.SettingsBody
import com.android.settingslib.spa.widget.ui.SettingsTitle
import com.android.settingslib.spaprivileged.model.app.PackageManagers
import com.android.settingslib.spaprivileged.R
import com.android.settingslib.spaprivileged.model.app.rememberAppRepository

class AppInfoProvider(private val packageInfo: PackageInfo) {
    @Composable
fun AppInfo(packageName: String, userId: Int) {
    fun AppInfo(displayVersion: Boolean = false) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
@@ -49,25 +53,34 @@ fun AppInfo(packageName: String, userId: Int) {
                ),
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
        val packageInfo =
            remember { PackageManagers.getPackageInfoAsUser(packageName, userId) } ?: return
            Box(modifier = Modifier.padding(SettingsDimension.itemPaddingAround)) {
                AppIcon(app = packageInfo.applicationInfo, size = SettingsDimension.appIconInfoSize)
            }
            AppLabel(packageInfo.applicationInfo)
        AppVersion(packageInfo.versionName)
            if (displayVersion) AppVersion()
        }
    }

    @Composable
private fun AppVersion(versionName: String?) {
    if (versionName == null) return
    private fun AppVersion() {
        if (packageInfo.versionName == null) return
        Spacer(modifier = Modifier.height(4.dp))
    SettingsBody(versionName)
        SettingsBody(packageInfo.versionName)
    }

    @Composable
fun AppIcon(app: ApplicationInfo, size: Dp) {
    fun FooterAppVersion() {
        if (packageInfo.versionName == null) return
        Divider()
        Box(modifier = Modifier.padding(SettingsDimension.itemPadding)) {
            val versionName = BidiFormatter.getInstance().unicodeWrap(packageInfo.versionName)
            SettingsBody(stringResource(R.string.version_text, versionName))
        }
    }
}

@Composable
internal fun AppIcon(app: ApplicationInfo, size: Dp) {
    val appRepository = rememberAppRepository()
    Image(
        painter = rememberDrawablePainter(appRepository.produceIcon(app).value),
@@ -77,7 +90,7 @@ fun AppIcon(app: ApplicationInfo, size: Dp) {
}

@Composable
fun AppLabel(app: ApplicationInfo) {
internal fun AppLabel(app: ApplicationInfo) {
    val appRepository = rememberAppRepository()
    SettingsTitle(appRepository.produceLabel(app))
}
+8 −1
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@
package com.android.settingslib.spaprivileged.template.app

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
import com.android.settingslib.spa.widget.ui.Footer
import com.android.settingslib.spaprivileged.model.app.PackageManagers

@Composable
fun AppInfoPage(
@@ -29,7 +31,12 @@ fun AppInfoPage(
    content: @Composable () -> Unit,
) {
    RegularScaffold(title = title) {
        AppInfo(packageName, userId)
        val appInfoProvider = remember {
            val packageInfo = PackageManagers.getPackageInfoAsUser(packageName, userId)
                ?: return@RegularScaffold
            AppInfoProvider(packageInfo)
        }
        appInfoProvider.AppInfo(displayVersion = true)

        content()

+25 −2
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import com.android.settingslib.spaprivileged.model.app.AppRecord
import com.android.settingslib.spaprivileged.model.app.PackageManagers
@@ -80,10 +82,31 @@ internal class TogglePermissionAppInfoPageProvider(

    companion object {
        @Composable
        internal fun navigator(permissionType: String, app: ApplicationInfo) =
        fun navigator(permissionType: String, app: ApplicationInfo) =
            navigator(route = "$PAGE_NAME/$permissionType/${app.toRoute()}")

        internal fun buildPageData(permissionType: String): SettingsPage {
        @Composable
        fun <T : AppRecord> EntryItem(
            permissionType: String,
            app: ApplicationInfo,
            listModel: TogglePermissionAppListModel<T>,
        ) {
            val context = LocalContext.current
            val internalListModel = remember {
                TogglePermissionInternalAppListModel(context, listModel)
            }
            val record = remember { listModel.transformItem(app) }
            if (!remember { listModel.isChangeable(record) }) return
            Preference(
                object : PreferenceModel {
                    override val title = stringResource(listModel.pageTitleResId)
                    override val summary = internalListModel.getSummary(record)
                    override val onClick = navigator(permissionType, app)
                }
            )
        }

        fun buildPageData(permissionType: String): SettingsPage {
            return SettingsPage.create(
                PAGE_NAME, PAGE_PARAMETER, bundleOf(PERMISSION to permissionType))
        }
+9 −18
Original line number Diff line number Diff line
@@ -20,13 +20,10 @@ 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.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.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

@@ -85,28 +82,22 @@ interface TogglePermissionAppListProvider {

    fun createModel(context: Context): TogglePermissionAppListModel<out AppRecord>

    fun buildInjectEntry(): SettingsEntryBuilder {
        return TogglePermissionAppListPageProvider.buildInjectEntry(permissionType)
    }

    @Composable
    fun EntryItem() {
        val listModel = rememberContext(::createModel)
        Preference(
            object : PreferenceModel {
                override val title = stringResource(listModel.pageTitleResId)
                override val onClick = TogglePermissionAppListPageProvider.navigator(permissionType)
            }
        )
    }
    fun buildAppListInjectEntry(): SettingsEntryBuilder =
        TogglePermissionAppListPageProvider.buildInjectEntry(permissionType) { createModel(it) }

    /**
     * Gets the route to the toggle permission App List page.
     *
     * Expose route to enable enter from non-SPA pages.
     */
    fun getRoute(): String =
    fun getAppListRoute(): String =
        TogglePermissionAppListPageProvider.getRoute(permissionType)

    @Composable
    fun InfoPageEntryItem(app: ApplicationInfo) {
        val listModel = rememberContext(::createModel)
        TogglePermissionAppInfoPageProvider.EntryItem(permissionType, app, listModel)
    }
}

class TogglePermissionAppListTemplate(
Loading