From 4aec2c906c98247944c3639796646c564f30ef43 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Thu, 29 Sep 2022 12:05:54 +0800 Subject: [PATCH] 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 --- .../spa/widget/scaffold/Actions.kt | 22 ++++++++++++++++++- .../framework/common/Contexts.kt | 11 ++++++++++ .../model/app/ApplicationInfos.kt | 12 ++++++++++ .../model/app/PackageManagers.kt | 7 +++++- .../spaprivileged/template/app/AppListPage.kt | 12 ++-------- .../app/TogglePermissionAppInfoPage.kt | 6 ++--- 6 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt index b8e43609708d4..6a88f2dd369ce 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt @@ -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, diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt new file mode 100644 index 0000000000000..7796549485b67 --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/common/Contexts.kt @@ -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)!! diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/ApplicationInfos.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/ApplicationInfos.kt index f9f75fb55d398..c1ac5d473dbac 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/ApplicationInfos.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/ApplicationInfos.kt @@ -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" diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/PackageManagers.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/PackageManagers.kt index 5c5caf5987178..215d22cd0c5ef 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/PackageManagers.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/PackageManagers.kt @@ -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 { diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListPage.kt index fb03d2c2e2cbe..2be1d1c6cce6b 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListPage.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListPage.kt @@ -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 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) }, ) diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt index 883eddff8054c..1bbc47d604d37 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt @@ -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 createSwitchModel( listModel: TogglePermissionAppListModel, packageName: String, userId: Int, -): TogglePermissionSwitchModel { +): TogglePermissionSwitchModel? { val record = remember { - val app = PackageManagers.getApplicationInfoAsUser(packageName, userId) + val app = PackageManagers.getApplicationInfoAsUser(packageName, userId) ?: return null listModel.transformItem(app) } val context = LocalContext.current