1 /* <lambda>null2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.spa.app.appinfo 18 19 import android.app.settings.SettingsEnums 20 import android.content.pm.ApplicationInfo 21 import android.os.UserManager 22 import androidx.annotation.VisibleForTesting 23 import androidx.compose.material.icons.Icons 24 import androidx.compose.material.icons.outlined.Report 25 import androidx.compose.material3.Text 26 import androidx.compose.runtime.Composable 27 import androidx.compose.runtime.remember 28 import androidx.compose.ui.res.stringResource 29 import androidx.lifecycle.compose.collectAsStateWithLifecycle 30 import com.android.settings.R 31 import com.android.settingslib.RestrictedLockUtils 32 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin 33 import com.android.settingslib.RestrictedLockUtilsInternal 34 import com.android.settingslib.spa.widget.button.ActionButton 35 import com.android.settingslib.spa.widget.dialog.AlertDialogButton 36 import com.android.settingslib.spa.widget.dialog.AlertDialogPresenter 37 import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter 38 import com.android.settingslib.spaprivileged.model.app.userId 39 40 class AppForceStopButton( 41 private val packageInfoPresenter: PackageInfoPresenter, 42 private val appForceStopRepository: AppForceStopRepository = 43 AppForceStopRepository(packageInfoPresenter), 44 ) { 45 private val context = packageInfoPresenter.context 46 private val packageManager = context.packageManager 47 48 @Composable 49 fun getActionButton(app: ApplicationInfo): ActionButton { 50 val dialogPresenter = confirmDialogPresenter() 51 return ActionButton( 52 text = stringResource(R.string.force_stop), 53 imageVector = Icons.Outlined.Report, 54 enabled = remember(app) { appForceStopRepository.canForceStopFlow() } 55 .collectAsStateWithLifecycle(false).value, 56 ) { onForceStopButtonClicked(app, dialogPresenter) } 57 } 58 59 private fun onForceStopButtonClicked( 60 app: ApplicationInfo, 61 dialogPresenter: AlertDialogPresenter, 62 ) { 63 packageInfoPresenter.logAction(SettingsEnums.ACTION_APP_INFO_FORCE_STOP) 64 getAdminRestriction(app)?.let { admin -> 65 RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin) 66 return 67 } 68 dialogPresenter.open() 69 } 70 71 @VisibleForTesting 72 fun getAdminRestriction(app: ApplicationInfo): EnforcedAdmin? = when { 73 packageManager.isPackageStateProtected(app.packageName, app.userId) -> { 74 RestrictedLockUtilsInternal.getDeviceOwner(context) ?: EnforcedAdmin() 75 } 76 77 else -> RestrictedLockUtilsInternal.checkIfRestrictionEnforced( 78 context, UserManager.DISALLOW_APPS_CONTROL, app.userId 79 ) 80 } 81 82 @Composable 83 private fun confirmDialogPresenter() = rememberAlertDialogPresenter( 84 confirmButton = AlertDialogButton( 85 text = stringResource(R.string.okay), 86 onClick = packageInfoPresenter::forceStop, 87 ), 88 dismissButton = AlertDialogButton(stringResource(R.string.cancel)), 89 title = stringResource(R.string.force_stop_dlg_title), 90 text = { Text(stringResource(R.string.force_stop_dlg_text)) }, 91 ) 92 } 93