Loading src/com/android/settings/spa/app/appinfo/AppButtons.kt +9 −9 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ package com.android.settings.spa.app.appinfo import android.content.pm.PackageInfo import android.content.pm.ApplicationInfo import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.remember Loading Loading @@ -58,17 +58,17 @@ private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoP @Composable fun rememberActionsButtons() = remember { packageInfoPresenter.flow.map { packageInfo -> if (packageInfo != null) getActionButtons(packageInfo) else emptyList() if (packageInfo != null) getActionButtons(packageInfo.applicationInfo) else emptyList() } }.collectAsState(initial = emptyList()) private fun getActionButtons(packageInfo: PackageInfo): List<ActionButton> = listOfNotNull( appLaunchButton.getActionButton(packageInfo), appInstallButton.getActionButton(packageInfo), appDisableButton.getActionButton(packageInfo), appUninstallButton.getActionButton(packageInfo), appClearButton.getActionButton(packageInfo), appForceStopButton.getActionButton(packageInfo), private fun getActionButtons(app: ApplicationInfo): List<ActionButton> = listOfNotNull( appLaunchButton.getActionButton(app), appInstallButton.getActionButton(app), appDisableButton.getActionButton(app), appUninstallButton.getActionButton(app), appClearButton.getActionButton(app), appForceStopButton.getActionButton(app), ) @Composable Loading src/com/android/settings/spa/app/appinfo/AppClearButton.kt +2 −3 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ package com.android.settings.spa.app.appinfo import android.content.pm.PackageInfo import android.content.pm.ApplicationInfo import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Delete import androidx.compose.material3.AlertDialog Loading @@ -37,8 +37,7 @@ class AppClearButton( private var openConfirmDialog by mutableStateOf(false) fun getActionButton(packageInfo: PackageInfo): ActionButton? { val app = packageInfo.applicationInfo fun getActionButton(app: ApplicationInfo): ActionButton? { if (!app.isInstantApp) return null return clearButton() Loading src/com/android/settings/spa/app/appinfo/AppDisableButton.kt +22 −26 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.settings.spa.app.appinfo import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ArrowCircleDown import androidx.compose.material.icons.outlined.HideSource Loading Loading @@ -52,13 +51,12 @@ class AppDisableButton( private var openConfirmDialog by mutableStateOf(false) fun getActionButton(packageInfo: PackageInfo): ActionButton? { val app = packageInfo.applicationInfo fun getActionButton(app: ApplicationInfo): ActionButton? { if (!app.isSystemApp) return null return when { app.enabled && !app.isDisabledUntilUsed -> { disableButton(app = app, enabled = isDisableButtonEnabled(packageInfo)) disableButton(app) } else -> enableButton() Loading @@ -68,38 +66,36 @@ class AppDisableButton( /** * Gets whether a package can be disabled. */ private fun isDisableButtonEnabled(packageInfo: PackageInfo): Boolean { val packageName = packageInfo.packageName val app = packageInfo.applicationInfo return when { private fun ApplicationInfo.canBeDisabled(): Boolean = when { // Try to prevent the user from bricking their phone by not allowing disabling of apps // signed with the system certificate. isSignedWithPlatformKey -> false // system/vendor resource overlays can never be disabled. isResourceOverlay -> false packageName in applicationFeatureProvider.keepEnabledPackages -> false // Home launcher apps need special handling. In system ones we don't risk downgrading // because that can interfere with home-key resolution. packageName in appButtonRepository.getHomePackageInfo().homePackages -> false // Try to prevent the user from bricking their phone by not allowing disabling of apps // signed with the system certificate. SettingsLibUtils.isSystemPackage(resources, packageManager, packageInfo) -> false SettingsLibUtils.isEssentialPackage(resources, packageManager, packageName) -> false // We don't allow disabling DO/PO on *any* users if it's a system app, because // "disabling" is actually "downgrade to the system version + disable", and "downgrade" // will clear data on all users. Utils.isProfileOrDeviceOwner(userManager, devicePolicyManager, packageName) -> false appButtonRepository.isDisallowControl(app) -> false // system/vendor resource overlays can never be disabled. app.isResourceOverlay -> false appButtonRepository.isDisallowControl(this) -> false else -> true } } private fun disableButton(app: ApplicationInfo, enabled: Boolean) = ActionButton( private fun disableButton(app: ApplicationInfo) = ActionButton( text = context.getString(R.string.disable_text), imageVector = Icons.Outlined.HideSource, enabled = enabled, enabled = app.canBeDisabled(), ) { // Currently we apply the same device policy for both the uninstallation and disable button. if (!appButtonRepository.isUninstallBlockedByAdmin(app)) { Loading src/com/android/settings/spa/app/appinfo/AppForceStopButton.kt +1 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.settings.spa.app.appinfo import android.app.settings.SettingsEnums import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import android.os.UserManager import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.WarningAmber Loading Loading @@ -48,8 +47,7 @@ class AppForceStopButton( private var openConfirmDialog by mutableStateOf(false) fun getActionButton(packageInfo: PackageInfo): ActionButton { val app = packageInfo.applicationInfo fun getActionButton(app: ApplicationInfo): ActionButton { return ActionButton( text = context.getString(R.string.force_stop), imageVector = Icons.Outlined.WarningAmber, Loading src/com/android/settings/spa/app/appinfo/AppInstallButton.kt +1 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.settings.spa.app.appinfo import android.content.Intent import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.FileDownload import com.android.settings.R Loading @@ -29,8 +28,7 @@ import com.android.settingslib.spaprivileged.model.app.userHandle class AppInstallButton(private val packageInfoPresenter: PackageInfoPresenter) { private val context = packageInfoPresenter.context fun getActionButton(packageInfo: PackageInfo): ActionButton? { val app = packageInfo.applicationInfo fun getActionButton(app: ApplicationInfo): ActionButton? { if (!app.isInstantApp) return null return AppStoreUtil.getAppStoreLink(packageInfoPresenter.userContext, app.packageName) Loading Loading
src/com/android/settings/spa/app/appinfo/AppButtons.kt +9 −9 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ package com.android.settings.spa.app.appinfo import android.content.pm.PackageInfo import android.content.pm.ApplicationInfo import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.remember Loading Loading @@ -58,17 +58,17 @@ private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoP @Composable fun rememberActionsButtons() = remember { packageInfoPresenter.flow.map { packageInfo -> if (packageInfo != null) getActionButtons(packageInfo) else emptyList() if (packageInfo != null) getActionButtons(packageInfo.applicationInfo) else emptyList() } }.collectAsState(initial = emptyList()) private fun getActionButtons(packageInfo: PackageInfo): List<ActionButton> = listOfNotNull( appLaunchButton.getActionButton(packageInfo), appInstallButton.getActionButton(packageInfo), appDisableButton.getActionButton(packageInfo), appUninstallButton.getActionButton(packageInfo), appClearButton.getActionButton(packageInfo), appForceStopButton.getActionButton(packageInfo), private fun getActionButtons(app: ApplicationInfo): List<ActionButton> = listOfNotNull( appLaunchButton.getActionButton(app), appInstallButton.getActionButton(app), appDisableButton.getActionButton(app), appUninstallButton.getActionButton(app), appClearButton.getActionButton(app), appForceStopButton.getActionButton(app), ) @Composable Loading
src/com/android/settings/spa/app/appinfo/AppClearButton.kt +2 −3 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ package com.android.settings.spa.app.appinfo import android.content.pm.PackageInfo import android.content.pm.ApplicationInfo import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Delete import androidx.compose.material3.AlertDialog Loading @@ -37,8 +37,7 @@ class AppClearButton( private var openConfirmDialog by mutableStateOf(false) fun getActionButton(packageInfo: PackageInfo): ActionButton? { val app = packageInfo.applicationInfo fun getActionButton(app: ApplicationInfo): ActionButton? { if (!app.isInstantApp) return null return clearButton() Loading
src/com/android/settings/spa/app/appinfo/AppDisableButton.kt +22 −26 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.settings.spa.app.appinfo import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ArrowCircleDown import androidx.compose.material.icons.outlined.HideSource Loading Loading @@ -52,13 +51,12 @@ class AppDisableButton( private var openConfirmDialog by mutableStateOf(false) fun getActionButton(packageInfo: PackageInfo): ActionButton? { val app = packageInfo.applicationInfo fun getActionButton(app: ApplicationInfo): ActionButton? { if (!app.isSystemApp) return null return when { app.enabled && !app.isDisabledUntilUsed -> { disableButton(app = app, enabled = isDisableButtonEnabled(packageInfo)) disableButton(app) } else -> enableButton() Loading @@ -68,38 +66,36 @@ class AppDisableButton( /** * Gets whether a package can be disabled. */ private fun isDisableButtonEnabled(packageInfo: PackageInfo): Boolean { val packageName = packageInfo.packageName val app = packageInfo.applicationInfo return when { private fun ApplicationInfo.canBeDisabled(): Boolean = when { // Try to prevent the user from bricking their phone by not allowing disabling of apps // signed with the system certificate. isSignedWithPlatformKey -> false // system/vendor resource overlays can never be disabled. isResourceOverlay -> false packageName in applicationFeatureProvider.keepEnabledPackages -> false // Home launcher apps need special handling. In system ones we don't risk downgrading // because that can interfere with home-key resolution. packageName in appButtonRepository.getHomePackageInfo().homePackages -> false // Try to prevent the user from bricking their phone by not allowing disabling of apps // signed with the system certificate. SettingsLibUtils.isSystemPackage(resources, packageManager, packageInfo) -> false SettingsLibUtils.isEssentialPackage(resources, packageManager, packageName) -> false // We don't allow disabling DO/PO on *any* users if it's a system app, because // "disabling" is actually "downgrade to the system version + disable", and "downgrade" // will clear data on all users. Utils.isProfileOrDeviceOwner(userManager, devicePolicyManager, packageName) -> false appButtonRepository.isDisallowControl(app) -> false // system/vendor resource overlays can never be disabled. app.isResourceOverlay -> false appButtonRepository.isDisallowControl(this) -> false else -> true } } private fun disableButton(app: ApplicationInfo, enabled: Boolean) = ActionButton( private fun disableButton(app: ApplicationInfo) = ActionButton( text = context.getString(R.string.disable_text), imageVector = Icons.Outlined.HideSource, enabled = enabled, enabled = app.canBeDisabled(), ) { // Currently we apply the same device policy for both the uninstallation and disable button. if (!appButtonRepository.isUninstallBlockedByAdmin(app)) { Loading
src/com/android/settings/spa/app/appinfo/AppForceStopButton.kt +1 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.settings.spa.app.appinfo import android.app.settings.SettingsEnums import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import android.os.UserManager import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.WarningAmber Loading Loading @@ -48,8 +47,7 @@ class AppForceStopButton( private var openConfirmDialog by mutableStateOf(false) fun getActionButton(packageInfo: PackageInfo): ActionButton { val app = packageInfo.applicationInfo fun getActionButton(app: ApplicationInfo): ActionButton { return ActionButton( text = context.getString(R.string.force_stop), imageVector = Icons.Outlined.WarningAmber, Loading
src/com/android/settings/spa/app/appinfo/AppInstallButton.kt +1 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.settings.spa.app.appinfo import android.content.Intent import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.FileDownload import com.android.settings.R Loading @@ -29,8 +28,7 @@ import com.android.settingslib.spaprivileged.model.app.userHandle class AppInstallButton(private val packageInfoPresenter: PackageInfoPresenter) { private val context = packageInfoPresenter.context fun getActionButton(packageInfo: PackageInfo): ActionButton? { val app = packageInfo.applicationInfo fun getActionButton(app: ApplicationInfo): ActionButton? { if (!app.isInstantApp) return null return AppStoreUtil.getAppStoreLink(packageInfoPresenter.userContext, app.packageName) Loading