Loading src/com/android/settings/spa/app/appinfo/AppButtons.kt +6 −15 Original line number Diff line number Diff line Loading @@ -24,14 +24,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.settingslib.applications.AppUtils import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spa.widget.button.ActionButtons import kotlinx.coroutines.flow.map @Composable fun AppButtons(packageInfoPresenter: PackageInfoPresenter) { if (remember(packageInfoPresenter) { packageInfoPresenter.isMainlineModule() }) return val presenter = remember { AppButtonsPresenter(packageInfoPresenter) } presenter.Dialogs() ActionButtons(actionButtons = presenter.rememberActionsButtons().value) ActionButtons(actionButtons = presenter.getActionButtons()) } private fun PackageInfoPresenter.isMainlineModule(): Boolean = Loading @@ -47,12 +45,12 @@ private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoP @OptIn(ExperimentalLifecycleComposeApi::class) @Composable fun rememberActionsButtons() = remember { packageInfoPresenter.flow.map { packageInfo -> if (packageInfo != null) getActionButtons(packageInfo.applicationInfo) else emptyList() } }.collectAsStateWithLifecycle(initialValue = emptyList()) fun getActionButtons() = packageInfoPresenter.flow.collectAsStateWithLifecycle(initialValue = null).value?.let { getActionButtons(it.applicationInfo) } ?: emptyList() @Composable private fun getActionButtons(app: ApplicationInfo): List<ActionButton> = listOfNotNull( appLaunchButton.getActionButton(app), appInstallButton.getActionButton(app), Loading @@ -61,11 +59,4 @@ private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoP appClearButton.getActionButton(app), appForceStopButton.getActionButton(app), ) @Composable fun Dialogs() { appDisableButton.DisableConfirmDialog() appClearButton.ClearConfirmDialog() appForceStopButton.ForceStopConfirmDialog() } } src/com/android/settings/spa/app/appinfo/AppClearButton.kt +20 −37 Original line number Diff line number Diff line Loading @@ -19,61 +19,44 @@ package com.android.settings.spa.app.appinfo import android.content.pm.ApplicationInfo import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Delete import androidx.compose.material3.AlertDialog import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter class AppClearButton( private val packageInfoPresenter: PackageInfoPresenter, ) { private val context = packageInfoPresenter.context private var openConfirmDialog by mutableStateOf(false) @Composable fun getActionButton(app: ApplicationInfo): ActionButton? { if (!app.isInstantApp) return null return clearButton() } private fun clearButton() = ActionButton( @Composable private fun clearButton(): ActionButton { val dialogPresenter = confirmDialogPresenter() return ActionButton( text = context.getString(R.string.clear_instant_app_data), imageVector = Icons.Outlined.Delete, ) { openConfirmDialog = true } onClick = dialogPresenter::open, ) } @Composable fun ClearConfirmDialog() { if (!openConfirmDialog) return AlertDialog( onDismissRequest = { openConfirmDialog = false }, confirmButton = { TextButton( onClick = { openConfirmDialog = false packageInfoPresenter.clearInstantApp() }, ) { Text(stringResource(R.string.clear_instant_app_data)) } }, dismissButton = { TextButton(onClick = { openConfirmDialog = false }) { Text(stringResource(R.string.cancel)) } }, title = { Text(stringResource(R.string.clear_instant_app_data)) }, text = { Text(stringResource(R.string.clear_instant_app_confirmation)) }, private fun confirmDialogPresenter() = rememberAlertDialogPresenter( confirmButton = AlertDialogButton( text = stringResource(R.string.clear_instant_app_data), onClick = packageInfoPresenter::clearInstantApp, ), dismissButton = AlertDialogButton(stringResource(R.string.cancel)), title = stringResource(R.string.clear_instant_app_data), text = { Text(stringResource(R.string.clear_instant_app_confirmation)) }, ) } } src/com/android/settings/spa/app/appinfo/AppDisableButton.kt +25 −39 Original line number Diff line number Diff line Loading @@ -20,18 +20,15 @@ import android.content.pm.ApplicationInfo import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ArrowCircleDown import androidx.compose.material.icons.outlined.HideSource import androidx.compose.material3.AlertDialog import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settings.Utils import com.android.settings.overlay.FeatureFactory import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager import com.android.settingslib.spaprivileged.framework.common.userManager import com.android.settingslib.spaprivileged.model.app.isDisabledUntilUsed Loading @@ -49,8 +46,7 @@ class AppDisableButton( private val applicationFeatureProvider = FeatureFactory.getFactory(context).getApplicationFeatureProvider(context) private var openConfirmDialog by mutableStateOf(false) @Composable fun getActionButton(app: ApplicationInfo): ActionButton? { if (!app.isSystemApp) return null Loading Loading @@ -92,14 +88,19 @@ class AppDisableButton( else -> true } private fun disableButton(app: ApplicationInfo) = ActionButton( @Composable private fun disableButton(app: ApplicationInfo): ActionButton { val dialogPresenter = confirmDialogPresenter() return ActionButton( text = context.getString(R.string.disable_text), imageVector = Icons.Outlined.HideSource, enabled = app.canBeDisabled(), ) { // Currently we apply the same device policy for both the uninstallation and disable button. // Currently we apply the same device policy for both the uninstallation and disable // button. if (!appButtonRepository.isUninstallBlockedByAdmin(app)) { openConfirmDialog = true dialogPresenter.open() } } } Loading @@ -109,28 +110,13 @@ class AppDisableButton( ) { packageInfoPresenter.enable() } @Composable fun DisableConfirmDialog() { if (!openConfirmDialog) return AlertDialog( onDismissRequest = { openConfirmDialog = false }, confirmButton = { TextButton( onClick = { openConfirmDialog = false packageInfoPresenter.disable() }, ) { Text(stringResource(R.string.app_disable_dlg_positive)) } }, dismissButton = { TextButton(onClick = { openConfirmDialog = false }) { Text(stringResource(R.string.cancel)) } }, text = { Text(stringResource(R.string.app_disable_dlg_text)) }, private fun confirmDialogPresenter() = rememberAlertDialogPresenter( confirmButton = AlertDialogButton( text = stringResource(R.string.reset_app_preferences_button), onClick = packageInfoPresenter::disable, ), dismissButton = AlertDialogButton(stringResource(R.string.cancel)), title = stringResource(R.string.app_disable_dlg_positive), text = { Text(stringResource(R.string.app_disable_dlg_text)) }, ) } } src/com/android/settings/spa/app/appinfo/AppForceStopButton.kt +20 −37 Original line number Diff line number Diff line Loading @@ -21,19 +21,17 @@ import android.content.pm.ApplicationInfo import android.os.UserManager import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material3.AlertDialog import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settingslib.RestrictedLockUtils import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin import com.android.settingslib.RestrictedLockUtilsInternal import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.AlertDialogPresenter import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter import com.android.settingslib.spaprivileged.model.app.hasFlag import com.android.settingslib.spaprivileged.model.app.isActiveAdmin import com.android.settingslib.spaprivileged.model.app.userId Loading @@ -45,14 +43,14 @@ class AppForceStopButton( private val appButtonRepository = AppButtonRepository(context) private val packageManager = context.packageManager private var openConfirmDialog by mutableStateOf(false) @Composable fun getActionButton(app: ApplicationInfo): ActionButton { val dialogPresenter = confirmDialogPresenter() return ActionButton( text = context.getString(R.string.force_stop), imageVector = Icons.Outlined.WarningAmber, enabled = isForceStopButtonEnable(app), ) { onForceStopButtonClicked(app) } ) { onForceStopButtonClicked(app, dialogPresenter) } } /** Loading @@ -68,13 +66,16 @@ class AppForceStopButton( else -> !app.hasFlag(ApplicationInfo.FLAG_STOPPED) } private fun onForceStopButtonClicked(app: ApplicationInfo) { private fun onForceStopButtonClicked( app: ApplicationInfo, dialogPresenter: AlertDialogPresenter, ) { packageInfoPresenter.logAction(SettingsEnums.ACTION_APP_INFO_FORCE_STOP) getAdminRestriction(app)?.let { admin -> RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin) return } openConfirmDialog = true dialogPresenter.open() } private fun getAdminRestriction(app: ApplicationInfo): EnforcedAdmin? = when { Loading @@ -88,31 +89,13 @@ class AppForceStopButton( } @Composable fun ForceStopConfirmDialog() { if (!openConfirmDialog) return AlertDialog( onDismissRequest = { openConfirmDialog = false }, confirmButton = { TextButton( onClick = { openConfirmDialog = false packageInfoPresenter.forceStop() }, ) { Text(stringResource(R.string.okay)) } }, dismissButton = { TextButton(onClick = { openConfirmDialog = false }) { Text(stringResource(R.string.cancel)) } }, title = { Text(stringResource(R.string.force_stop_dlg_title)) }, text = { Text(stringResource(R.string.force_stop_dlg_text)) }, private fun confirmDialogPresenter() = rememberAlertDialogPresenter( confirmButton = AlertDialogButton( text = stringResource(R.string.okay), onClick = packageInfoPresenter::forceStop, ), dismissButton = AlertDialogButton(stringResource(R.string.cancel)), title = stringResource(R.string.force_stop_dlg_title), text = { Text(stringResource(R.string.force_stop_dlg_text)) }, ) } } tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppDisableButtonTest.kt +19 −6 Original line number Diff line number Diff line Loading @@ -21,16 +21,19 @@ import android.content.Context import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.os.UserManager import androidx.compose.ui.test.junit4.createComposeRule import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.settings.Utils import com.android.settings.testutils.FakeFeatureFactory import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager import com.android.settingslib.spaprivileged.framework.common.userManager import com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock Loading @@ -42,6 +45,8 @@ import org.mockito.Mockito.`when` as whenever @RunWith(AndroidJUnit4::class) class AppDisableButtonTest { @get:Rule val composeTestRule = createComposeRule() private lateinit var mockSession: MockitoSession Loading Loading @@ -97,7 +102,7 @@ class AppDisableButtonTest { privateFlags = privateFlags or ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY } val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isFalse() } Loading @@ -108,7 +113,7 @@ class AppDisableButtonTest { privateFlags = privateFlags or ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY } val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isFalse() } Loading @@ -118,7 +123,7 @@ class AppDisableButtonTest { whenever(appFeatureProvider.keepEnabledPackages).thenReturn(setOf(PACKAGE_NAME)) val app = enabledSystemApp() val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isFalse() } Loading @@ -130,7 +135,7 @@ class AppDisableButtonTest { ).thenReturn(true) val app = enabledSystemApp() val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isFalse() } Loading @@ -141,7 +146,7 @@ class AppDisableButtonTest { .thenReturn(true) val app = enabledSystemApp() val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isFalse() } Loading @@ -150,11 +155,19 @@ class AppDisableButtonTest { fun getActionButton_regularEnabledSystemApp_canDisable() { val app = enabledSystemApp() val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isTrue() } private fun setDisableButton(app: ApplicationInfo): ActionButton { lateinit var actionButton: ActionButton composeTestRule.setContent { actionButton = appDisableButton.getActionButton(app)!! } return actionButton } private fun enabledSystemApp(builder: ApplicationInfo.() -> Unit = {}) = ApplicationInfo().apply { packageName = PACKAGE_NAME Loading Loading
src/com/android/settings/spa/app/appinfo/AppButtons.kt +6 −15 Original line number Diff line number Diff line Loading @@ -24,14 +24,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.settingslib.applications.AppUtils import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spa.widget.button.ActionButtons import kotlinx.coroutines.flow.map @Composable fun AppButtons(packageInfoPresenter: PackageInfoPresenter) { if (remember(packageInfoPresenter) { packageInfoPresenter.isMainlineModule() }) return val presenter = remember { AppButtonsPresenter(packageInfoPresenter) } presenter.Dialogs() ActionButtons(actionButtons = presenter.rememberActionsButtons().value) ActionButtons(actionButtons = presenter.getActionButtons()) } private fun PackageInfoPresenter.isMainlineModule(): Boolean = Loading @@ -47,12 +45,12 @@ private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoP @OptIn(ExperimentalLifecycleComposeApi::class) @Composable fun rememberActionsButtons() = remember { packageInfoPresenter.flow.map { packageInfo -> if (packageInfo != null) getActionButtons(packageInfo.applicationInfo) else emptyList() } }.collectAsStateWithLifecycle(initialValue = emptyList()) fun getActionButtons() = packageInfoPresenter.flow.collectAsStateWithLifecycle(initialValue = null).value?.let { getActionButtons(it.applicationInfo) } ?: emptyList() @Composable private fun getActionButtons(app: ApplicationInfo): List<ActionButton> = listOfNotNull( appLaunchButton.getActionButton(app), appInstallButton.getActionButton(app), Loading @@ -61,11 +59,4 @@ private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoP appClearButton.getActionButton(app), appForceStopButton.getActionButton(app), ) @Composable fun Dialogs() { appDisableButton.DisableConfirmDialog() appClearButton.ClearConfirmDialog() appForceStopButton.ForceStopConfirmDialog() } }
src/com/android/settings/spa/app/appinfo/AppClearButton.kt +20 −37 Original line number Diff line number Diff line Loading @@ -19,61 +19,44 @@ package com.android.settings.spa.app.appinfo import android.content.pm.ApplicationInfo import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Delete import androidx.compose.material3.AlertDialog import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter class AppClearButton( private val packageInfoPresenter: PackageInfoPresenter, ) { private val context = packageInfoPresenter.context private var openConfirmDialog by mutableStateOf(false) @Composable fun getActionButton(app: ApplicationInfo): ActionButton? { if (!app.isInstantApp) return null return clearButton() } private fun clearButton() = ActionButton( @Composable private fun clearButton(): ActionButton { val dialogPresenter = confirmDialogPresenter() return ActionButton( text = context.getString(R.string.clear_instant_app_data), imageVector = Icons.Outlined.Delete, ) { openConfirmDialog = true } onClick = dialogPresenter::open, ) } @Composable fun ClearConfirmDialog() { if (!openConfirmDialog) return AlertDialog( onDismissRequest = { openConfirmDialog = false }, confirmButton = { TextButton( onClick = { openConfirmDialog = false packageInfoPresenter.clearInstantApp() }, ) { Text(stringResource(R.string.clear_instant_app_data)) } }, dismissButton = { TextButton(onClick = { openConfirmDialog = false }) { Text(stringResource(R.string.cancel)) } }, title = { Text(stringResource(R.string.clear_instant_app_data)) }, text = { Text(stringResource(R.string.clear_instant_app_confirmation)) }, private fun confirmDialogPresenter() = rememberAlertDialogPresenter( confirmButton = AlertDialogButton( text = stringResource(R.string.clear_instant_app_data), onClick = packageInfoPresenter::clearInstantApp, ), dismissButton = AlertDialogButton(stringResource(R.string.cancel)), title = stringResource(R.string.clear_instant_app_data), text = { Text(stringResource(R.string.clear_instant_app_confirmation)) }, ) } }
src/com/android/settings/spa/app/appinfo/AppDisableButton.kt +25 −39 Original line number Diff line number Diff line Loading @@ -20,18 +20,15 @@ import android.content.pm.ApplicationInfo import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ArrowCircleDown import androidx.compose.material.icons.outlined.HideSource import androidx.compose.material3.AlertDialog import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settings.Utils import com.android.settings.overlay.FeatureFactory import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager import com.android.settingslib.spaprivileged.framework.common.userManager import com.android.settingslib.spaprivileged.model.app.isDisabledUntilUsed Loading @@ -49,8 +46,7 @@ class AppDisableButton( private val applicationFeatureProvider = FeatureFactory.getFactory(context).getApplicationFeatureProvider(context) private var openConfirmDialog by mutableStateOf(false) @Composable fun getActionButton(app: ApplicationInfo): ActionButton? { if (!app.isSystemApp) return null Loading Loading @@ -92,14 +88,19 @@ class AppDisableButton( else -> true } private fun disableButton(app: ApplicationInfo) = ActionButton( @Composable private fun disableButton(app: ApplicationInfo): ActionButton { val dialogPresenter = confirmDialogPresenter() return ActionButton( text = context.getString(R.string.disable_text), imageVector = Icons.Outlined.HideSource, enabled = app.canBeDisabled(), ) { // Currently we apply the same device policy for both the uninstallation and disable button. // Currently we apply the same device policy for both the uninstallation and disable // button. if (!appButtonRepository.isUninstallBlockedByAdmin(app)) { openConfirmDialog = true dialogPresenter.open() } } } Loading @@ -109,28 +110,13 @@ class AppDisableButton( ) { packageInfoPresenter.enable() } @Composable fun DisableConfirmDialog() { if (!openConfirmDialog) return AlertDialog( onDismissRequest = { openConfirmDialog = false }, confirmButton = { TextButton( onClick = { openConfirmDialog = false packageInfoPresenter.disable() }, ) { Text(stringResource(R.string.app_disable_dlg_positive)) } }, dismissButton = { TextButton(onClick = { openConfirmDialog = false }) { Text(stringResource(R.string.cancel)) } }, text = { Text(stringResource(R.string.app_disable_dlg_text)) }, private fun confirmDialogPresenter() = rememberAlertDialogPresenter( confirmButton = AlertDialogButton( text = stringResource(R.string.reset_app_preferences_button), onClick = packageInfoPresenter::disable, ), dismissButton = AlertDialogButton(stringResource(R.string.cancel)), title = stringResource(R.string.app_disable_dlg_positive), text = { Text(stringResource(R.string.app_disable_dlg_text)) }, ) } }
src/com/android/settings/spa/app/appinfo/AppForceStopButton.kt +20 −37 Original line number Diff line number Diff line Loading @@ -21,19 +21,17 @@ import android.content.pm.ApplicationInfo import android.os.UserManager import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material3.AlertDialog import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settingslib.RestrictedLockUtils import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin import com.android.settingslib.RestrictedLockUtilsInternal import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.AlertDialogPresenter import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter import com.android.settingslib.spaprivileged.model.app.hasFlag import com.android.settingslib.spaprivileged.model.app.isActiveAdmin import com.android.settingslib.spaprivileged.model.app.userId Loading @@ -45,14 +43,14 @@ class AppForceStopButton( private val appButtonRepository = AppButtonRepository(context) private val packageManager = context.packageManager private var openConfirmDialog by mutableStateOf(false) @Composable fun getActionButton(app: ApplicationInfo): ActionButton { val dialogPresenter = confirmDialogPresenter() return ActionButton( text = context.getString(R.string.force_stop), imageVector = Icons.Outlined.WarningAmber, enabled = isForceStopButtonEnable(app), ) { onForceStopButtonClicked(app) } ) { onForceStopButtonClicked(app, dialogPresenter) } } /** Loading @@ -68,13 +66,16 @@ class AppForceStopButton( else -> !app.hasFlag(ApplicationInfo.FLAG_STOPPED) } private fun onForceStopButtonClicked(app: ApplicationInfo) { private fun onForceStopButtonClicked( app: ApplicationInfo, dialogPresenter: AlertDialogPresenter, ) { packageInfoPresenter.logAction(SettingsEnums.ACTION_APP_INFO_FORCE_STOP) getAdminRestriction(app)?.let { admin -> RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin) return } openConfirmDialog = true dialogPresenter.open() } private fun getAdminRestriction(app: ApplicationInfo): EnforcedAdmin? = when { Loading @@ -88,31 +89,13 @@ class AppForceStopButton( } @Composable fun ForceStopConfirmDialog() { if (!openConfirmDialog) return AlertDialog( onDismissRequest = { openConfirmDialog = false }, confirmButton = { TextButton( onClick = { openConfirmDialog = false packageInfoPresenter.forceStop() }, ) { Text(stringResource(R.string.okay)) } }, dismissButton = { TextButton(onClick = { openConfirmDialog = false }) { Text(stringResource(R.string.cancel)) } }, title = { Text(stringResource(R.string.force_stop_dlg_title)) }, text = { Text(stringResource(R.string.force_stop_dlg_text)) }, private fun confirmDialogPresenter() = rememberAlertDialogPresenter( confirmButton = AlertDialogButton( text = stringResource(R.string.okay), onClick = packageInfoPresenter::forceStop, ), dismissButton = AlertDialogButton(stringResource(R.string.cancel)), title = stringResource(R.string.force_stop_dlg_title), text = { Text(stringResource(R.string.force_stop_dlg_text)) }, ) } }
tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppDisableButtonTest.kt +19 −6 Original line number Diff line number Diff line Loading @@ -21,16 +21,19 @@ import android.content.Context import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.os.UserManager import androidx.compose.ui.test.junit4.createComposeRule import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.settings.Utils import com.android.settings.testutils.FakeFeatureFactory import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager import com.android.settingslib.spaprivileged.framework.common.userManager import com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock Loading @@ -42,6 +45,8 @@ import org.mockito.Mockito.`when` as whenever @RunWith(AndroidJUnit4::class) class AppDisableButtonTest { @get:Rule val composeTestRule = createComposeRule() private lateinit var mockSession: MockitoSession Loading Loading @@ -97,7 +102,7 @@ class AppDisableButtonTest { privateFlags = privateFlags or ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY } val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isFalse() } Loading @@ -108,7 +113,7 @@ class AppDisableButtonTest { privateFlags = privateFlags or ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY } val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isFalse() } Loading @@ -118,7 +123,7 @@ class AppDisableButtonTest { whenever(appFeatureProvider.keepEnabledPackages).thenReturn(setOf(PACKAGE_NAME)) val app = enabledSystemApp() val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isFalse() } Loading @@ -130,7 +135,7 @@ class AppDisableButtonTest { ).thenReturn(true) val app = enabledSystemApp() val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isFalse() } Loading @@ -141,7 +146,7 @@ class AppDisableButtonTest { .thenReturn(true) val app = enabledSystemApp() val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isFalse() } Loading @@ -150,11 +155,19 @@ class AppDisableButtonTest { fun getActionButton_regularEnabledSystemApp_canDisable() { val app = enabledSystemApp() val actionButton = appDisableButton.getActionButton(app)!! val actionButton = setDisableButton(app) assertThat(actionButton.enabled).isTrue() } private fun setDisableButton(app: ApplicationInfo): ActionButton { lateinit var actionButton: ActionButton composeTestRule.setContent { actionButton = appDisableButton.getActionButton(app)!! } return actionButton } private fun enabledSystemApp(builder: ApplicationInfo.() -> Unit = {}) = ApplicationInfo().apply { packageName = PACKAGE_NAME Loading