Update archive's button enable property whenever hibernation toggle
has changed its value Test: AppArchiveButtonTest Bug: 304257274 Change-Id: I95b8a2219a7d04437b5c7d217a520e8c8b05d395
This commit is contained in:
@@ -33,10 +33,15 @@ import com.android.settings.R
|
||||
import com.android.settingslib.spa.widget.button.ActionButton
|
||||
import com.android.settingslib.spaprivileged.framework.compose.DisposableBroadcastReceiverAsUser
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class AppArchiveButton(packageInfoPresenter: PackageInfoPresenter) {
|
||||
class AppArchiveButton(
|
||||
packageInfoPresenter: PackageInfoPresenter,
|
||||
private val isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>,
|
||||
) {
|
||||
private companion object {
|
||||
private const val LOG_TAG = "AppArchiveButton"
|
||||
private const val INTENT_ACTION = "com.android.settings.archive.action"
|
||||
@@ -65,18 +70,20 @@ class AppArchiveButton(packageInfoPresenter: PackageInfoPresenter) {
|
||||
text = context.getString(R.string.archive),
|
||||
imageVector = Icons.Outlined.CloudUpload,
|
||||
enabled = remember(app) {
|
||||
flow {
|
||||
emit(
|
||||
app.isActionButtonEnabled() && appButtonRepository.isAllowUninstallOrArchive(
|
||||
context,
|
||||
app
|
||||
)
|
||||
)
|
||||
isHibernationSwitchEnabledStateFlow.asStateFlow().map {
|
||||
it && isActionButtonEnabledForApp(app)
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}.collectAsStateWithLifecycle(false).value
|
||||
) { onArchiveClicked(app) }
|
||||
}
|
||||
|
||||
private fun isActionButtonEnabledForApp(app: ApplicationInfo): Boolean {
|
||||
return app.isActionButtonEnabled() && appButtonRepository.isAllowUninstallOrArchive(
|
||||
context,
|
||||
app
|
||||
)
|
||||
}
|
||||
|
||||
private fun ApplicationInfo.isActionButtonEnabled(): Boolean {
|
||||
return !isArchived
|
||||
&& userPackageManager.isAppArchivable(packageName)
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.content.om.OverlayManager
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.util.Log
|
||||
import com.android.settingslib.RestrictedLockUtils
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal
|
||||
import com.android.settingslib.Utils
|
||||
|
||||
@@ -25,6 +25,7 @@ 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.MutableStateFlow
|
||||
|
||||
@Composable
|
||||
/**
|
||||
@@ -32,10 +33,17 @@ import com.android.settingslib.spa.widget.button.ActionButtons
|
||||
*/
|
||||
fun AppButtons(
|
||||
packageInfoPresenter: PackageInfoPresenter,
|
||||
isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>,
|
||||
featureFlags: FeatureFlags = FeatureFlagsImpl()
|
||||
) {
|
||||
if (remember(packageInfoPresenter) { packageInfoPresenter.isMainlineModule() }) return
|
||||
val presenter = remember { AppButtonsPresenter(packageInfoPresenter, featureFlags) }
|
||||
val presenter = remember {
|
||||
AppButtonsPresenter(
|
||||
packageInfoPresenter,
|
||||
isHibernationSwitchEnabledStateFlow,
|
||||
featureFlags
|
||||
)
|
||||
}
|
||||
ActionButtons(actionButtons = presenter.getActionButtons())
|
||||
}
|
||||
|
||||
@@ -44,6 +52,7 @@ private fun PackageInfoPresenter.isMainlineModule(): Boolean =
|
||||
|
||||
private class AppButtonsPresenter(
|
||||
private val packageInfoPresenter: PackageInfoPresenter,
|
||||
isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>,
|
||||
private val featureFlags: FeatureFlags
|
||||
) {
|
||||
private val appLaunchButton = AppLaunchButton(packageInfoPresenter)
|
||||
@@ -52,7 +61,8 @@ private class AppButtonsPresenter(
|
||||
private val appUninstallButton = AppUninstallButton(packageInfoPresenter)
|
||||
private val appClearButton = AppClearButton(packageInfoPresenter)
|
||||
private val appForceStopButton = AppForceStopButton(packageInfoPresenter)
|
||||
private val appArchiveButton = AppArchiveButton(packageInfoPresenter)
|
||||
private val appArchiveButton =
|
||||
AppArchiveButton(packageInfoPresenter, isHibernationSwitchEnabledStateFlow)
|
||||
private val appRestoreButton = AppRestoreButton(packageInfoPresenter)
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -50,6 +50,7 @@ import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
import com.android.settingslib.spa.widget.ui.Category
|
||||
import com.android.settingslib.spaprivileged.model.app.toRoute
|
||||
import com.android.settingslib.spaprivileged.template.app.AppInfoProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
private const val PACKAGE_NAME = "packageName"
|
||||
private const val USER_ID = "userId"
|
||||
@@ -133,10 +134,11 @@ private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) {
|
||||
val packageInfo = packageInfoState.value ?: return@RegularScaffold
|
||||
val app = packageInfo.applicationInfo ?: return@RegularScaffold
|
||||
val appInfoProvider = remember(packageInfo) { AppInfoProvider(packageInfo) }
|
||||
val isHibernationSwitchEnabledStateFlow = MutableStateFlow(false)
|
||||
|
||||
appInfoProvider.AppInfo()
|
||||
|
||||
AppButtons(packageInfoPresenter)
|
||||
AppButtons(packageInfoPresenter, isHibernationSwitchEnabledStateFlow)
|
||||
|
||||
AppSettingsPreference(app)
|
||||
AppAllServicesPreference(app)
|
||||
@@ -152,7 +154,7 @@ private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) {
|
||||
DefaultAppShortcuts(app)
|
||||
|
||||
Category(title = stringResource(R.string.unused_apps_category)) {
|
||||
HibernationSwitchPreference(app)
|
||||
HibernationSwitchPreference(app, isHibernationSwitchEnabledStateFlow)
|
||||
}
|
||||
|
||||
Category(title = stringResource(R.string.advanced_apps)) {
|
||||
|
||||
@@ -48,11 +48,15 @@ import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.asExecutor
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@Composable
|
||||
fun HibernationSwitchPreference(app: ApplicationInfo) {
|
||||
fun HibernationSwitchPreference(
|
||||
app: ApplicationInfo,
|
||||
isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val presenter = remember(app) { HibernationSwitchPresenter(context, app) }
|
||||
if (!presenter.isAvailable()) return
|
||||
@@ -73,7 +77,14 @@ fun HibernationSwitchPreference(app: ApplicationInfo) {
|
||||
context.getString(R.string.unused_apps_switch_summary)
|
||||
}
|
||||
override val changeable = { isEligibleState }
|
||||
override val checked = { if (changeable()) isCheckedState.value else false }
|
||||
override val checked = {
|
||||
val result = if (changeable()) isCheckedState.value else false
|
||||
result.also { isChecked ->
|
||||
isChecked?.let {
|
||||
isHibernationSwitchEnabledStateFlow.value = it
|
||||
}
|
||||
}
|
||||
}
|
||||
override val onCheckedChange = presenter::onCheckedChange
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user