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:
@@ -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,
|
||||
|
||||
@@ -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)!!
|
||||
@@ -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"
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user