Also wrap the menu into MoreOptionsAction

To share the more identical logic between pages.
Also add some util functions.

Bug: 236346018
Test: Manual on App Settings page
Change-Id: Ia423b39d84ddaeb731bd4a01e4e8df936be990e5
This commit is contained in:
Chaohui Wang
2022-09-29 12:05:54 +08:00
parent 1712deb115
commit 4aec2c906c
6 changed files with 55 additions and 15 deletions

View File

@@ -16,12 +16,18 @@
package com.android.settingslib.spa.widget.scaffold
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
import com.android.settingslib.spa.framework.compose.LocalNavController
@@ -47,7 +53,21 @@ private fun BackAction(contentDescription: String, onClick: () -> Unit) {
}
@Composable
fun MoreOptionsAction(onClick: () -> Unit) {
fun MoreOptionsAction(
content: @Composable ColumnScope.(onDismissRequest: () -> Unit) -> Unit,
) {
var expanded by rememberSaveable { mutableStateOf(false) }
MoreOptionsActionButton { expanded = true }
val onDismissRequest = { expanded = false }
DropdownMenu(
expanded = expanded,
onDismissRequest = onDismissRequest,
content = { content(onDismissRequest) },
)
}
@Composable
private fun MoreOptionsActionButton(onClick: () -> Unit) {
IconButton(onClick) {
Icon(
imageVector = Icons.Outlined.MoreVert,

View File

@@ -0,0 +1,11 @@
package com.android.settingslib.spaprivileged.framework.common
import android.app.admin.DevicePolicyManager
import android.content.Context
import android.os.UserManager
/** The [UserManager] instance. */
val Context.userManager get() = getSystemService(UserManager::class.java)!!
/** The [DevicePolicyManager] instance. */
val Context.devicePolicyManager get() = getSystemService(DevicePolicyManager::class.java)!!

View File

@@ -16,9 +16,13 @@
package com.android.settingslib.spaprivileged.model.app
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.UserHandle
import android.os.UserManager
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
import com.android.settingslib.spaprivileged.framework.common.userManager
/** The user id for a given application. */
val ApplicationInfo.userId: Int
@@ -35,5 +39,13 @@ fun ApplicationInfo.hasFlag(flag: Int): Boolean = (flags and flag) > 0
val ApplicationInfo.isDisabledUntilUsed: Boolean
get() = enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
/** Checks whether the application is disallowed control. */
fun ApplicationInfo.isDisallowControl(context: Context) =
context.userManager.hasBaseUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userHandle)
/** Checks whether the application is an active admin. */
fun ApplicationInfo.isActiveAdmin(context: Context): Boolean =
context.devicePolicyManager.packageHasActiveAdmins(packageName, userId)
/** Converts to the route string which used in navigation. */
fun ApplicationInfo.toRoute() = "$packageName/$userId"

View File

@@ -32,9 +32,14 @@ object PackageManagers {
fun getPackageInfoAsUser(packageName: String, userId: Int): PackageInfo? =
getPackageInfoAsUser(packageName, 0, userId)
fun getApplicationInfoAsUser(packageName: String, userId: Int): ApplicationInfo =
fun getApplicationInfoAsUser(packageName: String, userId: Int): ApplicationInfo? =
PackageManager.getApplicationInfoAsUserCached(packageName, 0, userId)
/** Checks whether a package is installed for a given user. */
fun isPackageInstalledAsUser(packageName: String, userId: Int): Boolean =
getApplicationInfoAsUser(packageName, userId)?.hasFlag(ApplicationInfo.FLAG_INSTALLED)
?: false
fun ApplicationInfo.hasRequestPermission(permission: String): Boolean {
val packageInfo = getPackageInfoAsUser(packageName, PackageManager.GET_PERMISSIONS, userId)
return packageInfo?.requestedPermissions?.let {

View File

@@ -20,15 +20,12 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import com.android.settingslib.spa.framework.compose.stateOf
@@ -84,17 +81,12 @@ fun <T : AppRecord> AppListPage(
@Composable
private fun ShowSystemAction(showSystem: Boolean, setShowSystem: (showSystem: Boolean) -> Unit) {
var expanded by remember { mutableStateOf(false) }
MoreOptionsAction { expanded = true }
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
) {
MoreOptionsAction { onDismissRequest ->
val menuText = if (showSystem) R.string.menu_hide_system else R.string.menu_show_system
DropdownMenuItem(
text = { Text(stringResource(menuText)) },
onClick = {
expanded = false
onDismissRequest()
setShowSystem(!showSystem)
},
)

View File

@@ -128,7 +128,7 @@ private fun TogglePermissionAppInfoPage(
userId = userId,
footerText = stringResource(listModel.footerResId),
) {
val model = createSwitchModel(listModel, packageName, userId)
val model = createSwitchModel(listModel, packageName, userId) ?: return@AppInfoPage
LaunchedEffect(model, Dispatchers.Default) {
model.initState()
}
@@ -141,9 +141,9 @@ private fun <T : AppRecord> createSwitchModel(
listModel: TogglePermissionAppListModel<T>,
packageName: String,
userId: Int,
): TogglePermissionSwitchModel<T> {
): TogglePermissionSwitchModel<T>? {
val record = remember {
val app = PackageManagers.getApplicationInfoAsUser(packageName, userId)
val app = PackageManagers.getApplicationInfoAsUser(packageName, userId) ?: return null
listModel.transformItem(app)
}
val context = LocalContext.current