[Spa] Fix "State<T> as a parameter" of Preference

Bug: 292036686
Test: manual - with Settings
Test: unit tests
Change-Id: I8a9faaefe4780667a2747a4ef1573361d3258705
This commit is contained in:
Chaohui Wang
2023-11-02 14:54:53 +08:00
parent 855307c73e
commit 3b21249d72
37 changed files with 193 additions and 192 deletions

View File

@@ -46,14 +46,14 @@ import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry; import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.spaprivileged.template.app.AppListItemKt; import com.android.settingslib.spaprivileged.template.app.AppListItemModelKt;
import com.android.settingslib.spaprivileged.template.app.AppListPageKt; import com.android.settingslib.spaprivileged.template.app.AppListPageKt;
import com.android.settingslib.widget.LottieColorUtils; import com.android.settingslib.widget.LottieColorUtils;
import com.airbnb.lottie.LottieAnimationView; import com.airbnb.lottie.LottieAnimationView;
/** /**
* @deprecated Will be removed, use {@link AppListItemKt} {@link AppListPageKt} instead. * @deprecated Will be removed, use {@link AppListItemModelKt} {@link AppListPageKt} instead.
*/ */
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public class ApplicationViewHolder extends RecyclerView.ViewHolder { public class ApplicationViewHolder extends RecyclerView.ViewHolder {

View File

@@ -29,7 +29,6 @@ import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.scaffold.RegularScaffold
@@ -56,7 +55,7 @@ object AboutPhonePageProvider : SettingsPageProvider {
val deviceNamePresenter = remember { DeviceNamePresenter(context) } val deviceNamePresenter = remember { DeviceNamePresenter(context) }
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource(R.string.about_settings) override val title = stringResource(R.string.about_settings)
override val summary = deviceNamePresenter.deviceName.toState() override val summary = { deviceNamePresenter.deviceName }
override val onClick = navigator(name) override val onClick = navigator(name)
override val icon = @Composable { override val icon = @Composable {
SettingsIcon(imageVector = Icons.Outlined.PermDeviceInformation) SettingsIcon(imageVector = Icons.Outlined.PermDeviceInformation)

View File

@@ -24,7 +24,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import com.android.settings.R import com.android.settings.R
import com.android.settings.deviceinfo.DeviceNamePreferenceController import com.android.settings.deviceinfo.DeviceNamePreferenceController
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.AlertDialogButton
import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
@@ -48,7 +47,7 @@ object DeviceNamePreference {
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = override val title =
stringResource(R.string.my_device_info_device_name_preference_title) stringResource(R.string.my_device_info_device_name_preference_title)
override val summary = deviceNamePresenter.deviceName.toState() override val summary = { deviceNamePresenter.deviceName }
override val onClick = dialogPresenter::open override val onClick = dialogPresenter::open
}) })

View File

@@ -21,8 +21,6 @@ import android.content.pm.ApplicationInfo
import android.os.Bundle import android.os.Bundle
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import com.android.settings.R import com.android.settings.R
import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider
@@ -116,7 +114,7 @@ class AllAppListModel(
option: Int, option: Int,
recordListFlow: Flow<List<AppRecordWithSize>>, recordListFlow: Flow<List<AppRecordWithSize>>,
): Flow<List<AppRecordWithSize>> = recordListFlow.filterItem( ): Flow<List<AppRecordWithSize>> = recordListFlow.filterItem(
when (SpinnerItem.values().getOrNull(option)) { when (SpinnerItem.entries.getOrNull(option)) {
SpinnerItem.Enabled -> ({ it.app.enabled && !it.app.isInstantApp }) SpinnerItem.Enabled -> ({ it.app.enabled && !it.app.isInstantApp })
SpinnerItem.Disabled -> isDisabled SpinnerItem.Disabled -> isDisabled
SpinnerItem.Instant -> isInstant SpinnerItem.Instant -> isInstant
@@ -130,22 +128,20 @@ class AllAppListModel(
private val isInstant: (AppRecordWithSize) -> Boolean = { it.app.isInstantApp } private val isInstant: (AppRecordWithSize) -> Boolean = { it.app.isInstantApp }
@Composable @Composable
override fun getSummary(option: Int, record: AppRecordWithSize): State<String> { override fun getSummary(option: Int, record: AppRecordWithSize): () -> String {
val storageSummary = record.app.getStorageSummary() val storageSummary = record.app.getStorageSummary()
return remember { return {
derivedStateOf { val summaryList = mutableListOf(storageSummary.value)
storageSummary.value +
when { when {
!record.app.installed && !record.app.isArchived -> { !record.app.installed && !record.app.isArchived -> {
System.lineSeparator() + context.getString(R.string.not_installed) summaryList += context.getString(R.string.not_installed)
} }
isDisabled(record) -> { isDisabled(record) -> {
System.lineSeparator() + summaryList += context.getString(com.android.settingslib.R.string.disabled)
context.getString(com.android.settingslib.R.string.disabled)
}
else -> ""
} }
} }
summaryList.joinToString(separator = System.lineSeparator())
} }
} }

View File

@@ -30,7 +30,6 @@ import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.scaffold.RegularScaffold
@@ -54,10 +53,10 @@ object AppsMainPageProvider : SettingsPageProvider {
fun buildInjectEntry() = fun buildInjectEntry() =
SettingsEntryBuilder.createInject(owner = owner) SettingsEntryBuilder.createInject(owner = owner)
.setUiLayoutFn { .setUiLayoutFn {
val summary = stringResource(R.string.app_and_notification_dashboard_summary)
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource(R.string.apps_dashboard_title) override val title = stringResource(R.string.apps_dashboard_title)
override val summary = override val summary = { summary }
stringResource(R.string.app_and_notification_dashboard_summary).toState()
override val onClick = navigator(name) override val onClick = navigator(name)
override val icon = @Composable { override val icon = @Composable {
SettingsIcon(imageVector = Icons.Outlined.Apps) SettingsIcon(imageVector = Icons.Outlined.Apps)

View File

@@ -19,6 +19,7 @@ package com.android.settings.spa.app.appcompat
import android.content.Context import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -40,11 +41,12 @@ fun UserAspectRatioAppPreference(app: ApplicationInfo) {
val presenter = remember { UserAspectRatioAppPresenter(context, app) } val presenter = remember { UserAspectRatioAppPresenter(context, app) }
if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return
Preference(object : PreferenceModel { val summary by presenter.summaryFlow.collectAsStateWithLifecycle(
override val title = stringResource(R.string.aspect_ratio_experimental_title)
override val summary = presenter.summaryFlow.collectAsStateWithLifecycle(
initialValue = stringResource(R.string.summary_placeholder), initialValue = stringResource(R.string.summary_placeholder),
) )
Preference(object : PreferenceModel {
override val title = stringResource(R.string.aspect_ratio_experimental_title)
override val summary = { summary }
override val onClick = presenter::startActivity override val onClick = presenter::startActivity
}) })
} }

View File

@@ -28,7 +28,7 @@ import android.util.Log
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -41,15 +41,14 @@ import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.rememberContext import com.android.settingslib.spa.framework.compose.rememberContext
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.framework.theme.SettingsDimension import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.framework.util.asyncMap import com.android.settingslib.spa.framework.util.asyncMap
import com.android.settingslib.spa.framework.util.filterItem import com.android.settingslib.spa.framework.util.filterItem
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.illustration.Illustration import com.android.settingslib.spa.widget.illustration.Illustration
import com.android.settingslib.spa.widget.illustration.IllustrationModel import com.android.settingslib.spa.widget.illustration.IllustrationModel
import com.android.settingslib.spa.widget.illustration.ResourceType import com.android.settingslib.spa.widget.illustration.ResourceType
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.ui.SettingsBody import com.android.settingslib.spa.widget.ui.SettingsBody
import com.android.settingslib.spa.widget.ui.SpinnerOption import com.android.settingslib.spa.widget.ui.SpinnerOption
import com.android.settingslib.spaprivileged.model.app.AppListModel import com.android.settingslib.spaprivileged.model.app.AppListModel
@@ -80,12 +79,14 @@ object UserAspectRatioAppsPageProvider : SettingsPageProvider {
@Composable @Composable
@VisibleForTesting @VisibleForTesting
fun EntryItem() = fun EntryItem() {
val summary = getSummary()
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource(R.string.aspect_ratio_experimental_title) override val title = stringResource(R.string.aspect_ratio_experimental_title)
override val summary = getSummary().toState() override val summary = { summary }
override val onClick = navigator(name) override val onClick = navigator(name)
}) })
}
@VisibleForTesting @VisibleForTesting
fun buildInjectEntry() = SettingsEntryBuilder fun buildInjectEntry() = SettingsEntryBuilder
@@ -177,7 +178,7 @@ class UserAspectRatioAppListModel(private val context: Context)
option: Int, option: Int,
recordListFlow: Flow<List<UserAspectRatioAppListItemModel>> recordListFlow: Flow<List<UserAspectRatioAppListItemModel>>
): Flow<List<UserAspectRatioAppListItemModel>> = recordListFlow.filterItem( ): Flow<List<UserAspectRatioAppListItemModel>> = recordListFlow.filterItem(
when (SpinnerItem.values().getOrNull(option)) { when (SpinnerItem.entries.getOrNull(option)) {
SpinnerItem.Suggested -> ({ it.canDisplay && it.suggested }) SpinnerItem.Suggested -> ({ it.canDisplay && it.suggested })
SpinnerItem.Overridden -> ({ it.userOverride != USER_MIN_ASPECT_RATIO_UNSET }) SpinnerItem.Overridden -> ({ it.userOverride != USER_MIN_ASPECT_RATIO_UNSET })
else -> ({ it.canDisplay }) else -> ({ it.canDisplay })
@@ -185,13 +186,15 @@ class UserAspectRatioAppListModel(private val context: Context)
) )
@Composable @Composable
override fun getSummary(option: Int, record: UserAspectRatioAppListItemModel) : State<String> = override fun getSummary(option: Int, record: UserAspectRatioAppListItemModel): () -> String {
remember(record.userOverride) { val summary by remember(record.userOverride) {
flow { flow {
emit(userAspectRatioManager.getUserMinAspectRatioEntry(record.userOverride, emit(userAspectRatioManager.getUserMinAspectRatioEntry(record.userOverride,
record.app.packageName)) record.app.packageName))
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
}.collectAsStateWithLifecycle(initialValue = stringResource(R.string.summary_placeholder)) }.collectAsStateWithLifecycle(initialValue = stringResource(R.string.summary_placeholder))
return { summary }
}
private fun getPackageAndActivityInfo(app: ApplicationInfo): PackageInfo? = try { private fun getPackageAndActivityInfo(app: ApplicationInfo): PackageInfo? = try {
packageManager.getPackageInfoAsUser(app.packageName, GET_ACTIVITIES_FLAGS, app.userId) packageManager.getPackageInfoAsUser(app.packageName, GET_ACTIVITIES_FLAGS, app.userId)

View File

@@ -24,6 +24,7 @@ import android.content.res.Resources
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@@ -52,11 +53,12 @@ fun AppAllServicesPreference(app: ApplicationInfo) {
val presenter = remember { AppAllServicesPresenter(context, app, coroutineScope) } val presenter = remember { AppAllServicesPresenter(context, app, coroutineScope) }
if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return
Preference(object : PreferenceModel { val summary by presenter.summaryFlow.collectAsStateWithLifecycle(
override val title = stringResource(R.string.app_info_all_services_label)
override val summary = presenter.summaryFlow.collectAsStateWithLifecycle(
initialValue = stringResource(R.string.summary_placeholder), initialValue = stringResource(R.string.summary_placeholder),
) )
Preference(object : PreferenceModel {
override val title = stringResource(R.string.app_info_all_services_label)
override val summary = { summary }
override val onClick = presenter::startActivity override val onClick = presenter::startActivity
}) })
} }

View File

@@ -21,7 +21,6 @@ import android.content.pm.ApplicationInfo
import android.util.Log import android.util.Log
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@@ -91,16 +90,17 @@ private class AppBatteryPresenter(private val context: Context, private val app:
} }
} }
val enabled = derivedStateOf { batteryDiffEntryState is LoadingState.Done } val enabled = { batteryDiffEntryState is LoadingState.Done }
val summary = derivedStateOf<String> { val summary = {
if (!app.installed) return@derivedStateOf "" if (app.installed) {
batteryDiffEntryState.let { batteryDiffEntryState -> batteryDiffEntryState.let { batteryDiffEntryState ->
when (batteryDiffEntryState) { when (batteryDiffEntryState) {
is LoadingState.Loading -> context.getString(R.string.summary_placeholder) is LoadingState.Loading -> context.getString(R.string.summary_placeholder)
is LoadingState.Done -> batteryDiffEntryState.result.getSummary() is LoadingState.Done -> batteryDiffEntryState.result.getSummary()
} }
} }
} else ""
} }
private fun BatteryDiffEntry?.getSummary(): String = private fun BatteryDiffEntry?.getSummary(): String =
@@ -155,7 +155,7 @@ private class AppBatteryPresenter(private val context: Context, private val app:
} }
private sealed class LoadingState<out T> { private sealed class LoadingState<out T> {
object Loading : LoadingState<Nothing>() data object Loading : LoadingState<Nothing>()
data class Done<T>(val result: T) : LoadingState<T>() data class Done<T>(val result: T) : LoadingState<T>()

View File

@@ -20,6 +20,7 @@ import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.net.NetworkTemplate import android.net.NetworkTemplate
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@@ -34,7 +35,6 @@ import com.android.settings.datausage.lib.IAppDataUsageSummaryRepository
import com.android.settings.datausage.lib.INetworkTemplates import com.android.settings.datausage.lib.INetworkTemplates
import com.android.settings.datausage.lib.NetworkTemplates import com.android.settings.datausage.lib.NetworkTemplates
import com.android.settings.datausage.lib.NetworkTemplates.getTitleResId import com.android.settings.datausage.lib.NetworkTemplates.getTitleResId
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.model.app.hasFlag import com.android.settingslib.spaprivileged.model.app.hasFlag
@@ -64,16 +64,17 @@ fun AppDataUsagePreference(
} }
if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return
val summary by presenter.summaryFlow.collectAsStateWithLifecycle(
initialValue = stringResource(R.string.computing_size),
)
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource( override val title = stringResource(
presenter.titleResIdFlow.collectAsStateWithLifecycle( presenter.titleResIdFlow.collectAsStateWithLifecycle(
initialValue = R.string.summary_placeholder, initialValue = R.string.summary_placeholder,
).value ).value
) )
override val summary = presenter.summaryFlow.collectAsStateWithLifecycle( override val summary = { summary }
initialValue = stringResource(R.string.computing_size), override val enabled = { presenter.isEnabled() }
)
override val enabled = presenter.isEnabled().toState()
override val onClick = presenter::startActivity override val onClick = presenter::startActivity
}) })
} }

View File

@@ -19,15 +19,16 @@ package com.android.settings.spa.app.appinfo
import android.content.Context import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R import com.android.settings.R
import com.android.settings.Utils import com.android.settings.Utils
import com.android.settings.applications.AppStoreUtil import com.android.settings.applications.AppStoreUtil
import com.android.settingslib.applications.AppUtils import com.android.settingslib.applications.AppUtils
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.framework.common.asUser import com.android.settingslib.spaprivileged.framework.common.asUser
@@ -49,13 +50,14 @@ fun AppInstallerInfoPreference(app: ApplicationInfo) {
val presenter = remember { AppInstallerInfoPresenter(context, app, coroutineScope) } val presenter = remember { AppInstallerInfoPresenter(context, app, coroutineScope) }
if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return
Preference(object : PreferenceModel { val summary by presenter.summaryFlow.collectAsStateWithLifecycle(
override val title = stringResource(R.string.app_install_details_title)
override val summary = presenter.summaryFlow.collectAsStateWithLifecycle(
initialValue = stringResource(R.string.summary_placeholder), initialValue = stringResource(R.string.summary_placeholder),
) )
override val enabled = val enabled by presenter.enabledFlow.collectAsStateWithLifecycle(initialValue = false)
presenter.enabledFlow.collectAsStateWithLifecycle(initialValue = false) Preference(object : PreferenceModel {
override val title = stringResource(R.string.app_install_details_title)
override val summary = { summary }
override val enabled = { enabled }
override val onClick = presenter::startActivity override val onClick = presenter::startActivity
}) })
} }

View File

@@ -23,15 +23,16 @@ import android.content.pm.PackageManager
import android.content.pm.PackageManager.ResolveInfoFlags import android.content.pm.PackageManager.ResolveInfoFlags
import android.net.Uri import android.net.Uri
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R import com.android.settings.R
import com.android.settings.applications.AppInfoBase import com.android.settings.applications.AppInfoBase
import com.android.settings.applications.AppLocaleUtil import com.android.settings.applications.AppLocaleUtil
import com.android.settings.applications.appinfo.AppLocaleDetails import com.android.settings.applications.appinfo.AppLocaleDetails
import com.android.settings.localepicker.AppLocalePickerActivity import com.android.settings.localepicker.AppLocalePickerActivity
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.model.app.userHandle import com.android.settingslib.spaprivileged.model.app.userHandle
@@ -46,11 +47,12 @@ fun AppLocalePreference(app: ApplicationInfo) {
val presenter = remember { AppLocalePresenter(context, app) } val presenter = remember { AppLocalePresenter(context, app) }
if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return
Preference(object : PreferenceModel { val summary by presenter.summaryFlow.collectAsStateWithLifecycle(
override val title = stringResource(R.string.app_locale_preference_title)
override val summary = presenter.summaryFlow.collectAsStateWithLifecycle(
initialValue = stringResource(R.string.summary_placeholder), initialValue = stringResource(R.string.summary_placeholder),
) )
Preference(object : PreferenceModel {
override val title = stringResource(R.string.app_locale_preference_title)
override val summary = { summary }
override val onClick = presenter::startActivity override val onClick = presenter::startActivity
}) })
} }

View File

@@ -19,6 +19,7 @@ package com.android.settings.spa.app.appinfo
import android.content.Context import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -29,7 +30,6 @@ import com.android.settings.notification.app.AppNotificationSettings
import com.android.settings.spa.notification.AppNotificationRepository import com.android.settings.spa.notification.AppNotificationRepository
import com.android.settings.spa.notification.IAppNotificationRepository import com.android.settings.spa.notification.IAppNotificationRepository
import com.android.settingslib.spa.framework.compose.rememberContext import com.android.settingslib.spa.framework.compose.rememberContext
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.model.app.installed import com.android.settingslib.spaprivileged.model.app.installed
@@ -43,17 +43,17 @@ fun AppNotificationPreference(
repository: IAppNotificationRepository = rememberContext(::AppNotificationRepository), repository: IAppNotificationRepository = rememberContext(::AppNotificationRepository),
) { ) {
val context = LocalContext.current val context = LocalContext.current
val summaryFlow = remember(app) { val summary by remember(app) {
flow { flow {
emit(repository.getNotificationSummary(app)) emit(repository.getNotificationSummary(app))
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.Default)
} }.collectAsStateWithLifecycle(
Preference(object : PreferenceModel {
override val title = stringResource(R.string.notifications_label)
override val summary = summaryFlow.collectAsStateWithLifecycle(
initialValue = stringResource(R.string.summary_placeholder) initialValue = stringResource(R.string.summary_placeholder)
) )
override val enabled = stateOf(app.installed) Preference(object : PreferenceModel {
override val title = stringResource(R.string.notifications_label)
override val summary = { summary }
override val enabled = { app.installed }
override val onClick = { navigateToAppNotificationSettings(context, app) } override val onClick = { navigateToAppNotificationSettings(context, app) }
}) })
} }

View File

@@ -19,6 +19,7 @@ package com.android.settings.spa.app.appinfo
import android.content.Context import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -28,7 +29,6 @@ import com.android.settings.applications.appinfo.AppInfoDashboardFragment
import com.android.settings.applications.intentpicker.AppLaunchSettings import com.android.settings.applications.intentpicker.AppLaunchSettings
import com.android.settings.applications.intentpicker.IntentPickerUtils import com.android.settings.applications.intentpicker.IntentPickerUtils
import com.android.settingslib.applications.AppUtils import com.android.settingslib.applications.AppUtils
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.framework.common.asUser import com.android.settingslib.spaprivileged.framework.common.asUser
@@ -46,12 +46,13 @@ fun AppOpenByDefaultPreference(app: ApplicationInfo) {
val presenter = remember(app) { AppOpenByDefaultPresenter(context, app) } val presenter = remember(app) { AppOpenByDefaultPresenter(context, app) }
if (remember(presenter) { !presenter.isAvailable() }) return if (remember(presenter) { !presenter.isAvailable() }) return
Preference(object : PreferenceModel { val summary by presenter.summaryFlow.collectAsStateWithLifecycle(
override val title = stringResource(R.string.launch_by_default)
override val summary = presenter.summaryFlow.collectAsStateWithLifecycle(
initialValue = stringResource(R.string.summary_placeholder), initialValue = stringResource(R.string.summary_placeholder),
) )
override val enabled = stateOf(presenter.isEnabled()) Preference(object : PreferenceModel {
override val title = stringResource(R.string.launch_by_default)
override val summary = { summary }
override val enabled = { presenter.isEnabled() }
override val onClick = presenter::startActivity override val onClick = presenter::startActivity
}) })
} }

View File

@@ -22,7 +22,6 @@ import android.content.Intent
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.util.Log import android.util.Log
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@@ -52,8 +51,8 @@ fun AppPermissionPreference(
model = remember { model = remember {
object : PreferenceModel { object : PreferenceModel {
override val title = context.getString(R.string.permissions_label) override val title = context.getString(R.string.permissions_label)
override val summary = derivedStateOf { summaryState.value.summary } override val summary = { summaryState.value.summary }
override val enabled = derivedStateOf { summaryState.value.enabled } override val enabled = { summaryState.value.enabled }
override val onClick = { startManagePermissionsActivity(context, app) } override val onClick = { startManagePermissionsActivity(context, app) }
} }
}, },

View File

@@ -19,9 +19,6 @@ package com.android.settings.spa.app.appinfo
import android.content.Context import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import com.android.settings.R import com.android.settings.R
@@ -47,12 +44,13 @@ fun AppStoragePreference(app: ApplicationInfo) {
} }
@Composable @Composable
private fun getSummary(context: Context, app: ApplicationInfo): State<String> { private fun getSummary(context: Context, app: ApplicationInfo): () -> String {
val sizeState = app.getStorageSize() val sizeState = app.getStorageSize()
return remember { return {
derivedStateOf {
val size = sizeState.value val size = sizeState.value
if (size.isBlank()) return@derivedStateOf context.getString(R.string.computing_size) if (size.isBlank()) {
context.getString(R.string.computing_size)
} else {
val storageType = context.getString( val storageType = context.getString(
when (app.hasFlag(ApplicationInfo.FLAG_EXTERNAL_STORAGE)) { when (app.hasFlag(ApplicationInfo.FLAG_EXTERNAL_STORAGE)) {
true -> R.string.storage_type_external true -> R.string.storage_type_external

View File

@@ -22,6 +22,7 @@ import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager.ResolveInfoFlags import android.content.pm.PackageManager.ResolveInfoFlags
import android.provider.Settings import android.provider.Settings
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@@ -29,7 +30,6 @@ import androidx.compose.ui.res.stringResource
import androidx.lifecycle.liveData import androidx.lifecycle.liveData
import com.android.settings.R import com.android.settings.R
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.model.app.hasFlag import com.android.settingslib.spaprivileged.model.app.hasFlag
@@ -43,12 +43,13 @@ fun AppTimeSpentPreference(app: ApplicationInfo) {
val presenter = remember { AppTimeSpentPresenter(context, app) } val presenter = remember { AppTimeSpentPresenter(context, app) }
if (!presenter.isAvailable()) return if (!presenter.isAvailable()) return
Preference(object : PreferenceModel { val summary by presenter.summaryLiveData.observeAsState(
override val title = stringResource(R.string.time_spent_in_app_pref_title)
override val summary = presenter.summaryLiveData.observeAsState(
initial = stringResource(R.string.summary_placeholder), initial = stringResource(R.string.summary_placeholder),
) )
override val enabled = stateOf(presenter.isEnabled()) Preference(object : PreferenceModel {
override val title = stringResource(R.string.time_spent_in_app_pref_title)
override val summary = { summary }
override val enabled = { presenter.isEnabled() }
override val onClick = presenter::startActivity override val onClick = presenter::startActivity
}) })
} }

View File

@@ -22,6 +22,7 @@ import android.content.Intent
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@@ -57,11 +58,12 @@ fun DefaultAppShortcutPreference(shortcut: DefaultAppShortcut, app: ApplicationI
if (remember(presenter) { !presenter.isAvailable() }) return if (remember(presenter) { !presenter.isAvailable() }) return
if (presenter.isVisible().observeAsState().value != true) return if (presenter.isVisible().observeAsState().value != true) return
Preference(object : PreferenceModel { val summary by presenter.summaryFlow.collectAsStateWithLifecycle(
override val title = stringResource(shortcut.titleResId)
override val summary = presenter.summaryFlow.collectAsStateWithLifecycle(
initialValue = stringResource(R.string.summary_placeholder), initialValue = stringResource(R.string.summary_placeholder),
) )
Preference(object : PreferenceModel {
override val title = stringResource(shortcut.titleResId)
override val summary = { summary }
override val onClick = presenter::startActivity override val onClick = presenter::startActivity
}) })
} }

View File

@@ -31,12 +31,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R import com.android.settings.R
import com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED import com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED
import com.android.settings.Utils.PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS import com.android.settings.Utils.PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS
import com.android.settingslib.spa.framework.compose.OverridableFlow import com.android.settingslib.spa.framework.compose.OverridableFlow
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreference
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import com.android.settingslib.spaprivileged.framework.common.appHibernationManager import com.android.settingslib.spaprivileged.framework.common.appHibernationManager
@@ -44,12 +43,12 @@ import com.android.settingslib.spaprivileged.framework.common.appOpsManager
import com.android.settingslib.spaprivileged.framework.common.asUser import com.android.settingslib.spaprivileged.framework.common.asUser
import com.android.settingslib.spaprivileged.framework.common.permissionControllerManager import com.android.settingslib.spaprivileged.framework.common.permissionControllerManager
import com.android.settingslib.spaprivileged.model.app.userHandle import com.android.settingslib.spaprivileged.model.app.userHandle
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
@Composable @Composable
fun HibernationSwitchPreference(app: ApplicationInfo) { fun HibernationSwitchPreference(app: ApplicationInfo) {
@@ -62,7 +61,7 @@ fun HibernationSwitchPreference(app: ApplicationInfo) {
SwitchPreference(remember { SwitchPreference(remember {
object : SwitchPreferenceModel { object : SwitchPreferenceModel {
override val title = context.getString(R.string.unused_apps_switch) override val title = context.getString(R.string.unused_apps_switch)
override val summary = stateOf(context.getString(R.string.unused_apps_switch_summary)) override val summary = { context.getString(R.string.unused_apps_switch_summary) }
override val changeable = isEligibleState override val changeable = isEligibleState
override val checked = derivedStateOf { override val checked = derivedStateOf {

View File

@@ -32,9 +32,9 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R import com.android.settings.R
import com.android.settings.Utils import com.android.settings.Utils
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settingslib.spa.framework.theme.SettingsDimension import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
@@ -53,11 +53,12 @@ fun InstantAppDomainsPreference(app: ApplicationInfo) {
val presenter = remember { InstantAppDomainsPresenter(context, app) } val presenter = remember { InstantAppDomainsPresenter(context, app) }
var openDialog by rememberSaveable { mutableStateOf(false) } var openDialog by rememberSaveable { mutableStateOf(false) }
Preference(object : PreferenceModel { val summary by presenter.summaryFlow.collectAsStateWithLifecycle(
override val title = stringResource(R.string.app_launch_supported_domain_urls_title)
override val summary = presenter.summaryFlow.collectAsStateWithLifecycle(
initialValue = stringResource(R.string.summary_placeholder), initialValue = stringResource(R.string.summary_placeholder),
) )
Preference(object : PreferenceModel {
override val title = stringResource(R.string.app_launch_supported_domain_urls_title)
override val summary = { summary }
override val onClick = { openDialog = true } override val onClick = { openDialog = true }
}) })

View File

@@ -19,13 +19,14 @@ package com.android.settings.spa.app.appinfo
import android.content.Context import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R import com.android.settings.R
import com.android.settings.applications.appinfo.AppInfoDashboardFragment import com.android.settings.applications.appinfo.AppInfoDashboardFragment
import com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesDetails import com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesDetails
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.framework.common.crossProfileApps import com.android.settingslib.spaprivileged.framework.common.crossProfileApps
@@ -39,11 +40,12 @@ fun InteractAcrossProfilesDetailsPreference(app: ApplicationInfo) {
val presenter = remember { InteractAcrossProfilesDetailsPresenter(context, app) } val presenter = remember { InteractAcrossProfilesDetailsPresenter(context, app) }
if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return
Preference(object : PreferenceModel { val summary by presenter.summaryFlow.collectAsStateWithLifecycle(
override val title = stringResource(R.string.interact_across_profiles_title)
override val summary = presenter.summaryFlow.collectAsStateWithLifecycle(
initialValue = stringResource(R.string.summary_placeholder), initialValue = stringResource(R.string.summary_placeholder),
) )
Preference(object : PreferenceModel {
override val title = stringResource(R.string.interact_across_profiles_title)
override val summary = { summary }
override val onClick = presenter::startActivity override val onClick = presenter::startActivity
}) })
} }

View File

@@ -32,6 +32,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.Delete
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState import androidx.compose.runtime.produceState
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@@ -88,9 +89,10 @@ object BackgroundInstalledAppsPageProvider : SettingsPageProvider {
@Composable @Composable
fun EntryItem() { fun EntryItem() {
if(featureIsDisabled) return if(featureIsDisabled) return
val summary by generatePreferenceSummary()
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource(R.string.background_install_title) override val title = stringResource(R.string.background_install_title)
override val summary = generatePreferenceSummary() override val summary = { summary }
override val onClick = navigator(name) override val onClick = navigator(name)
}) })
} }

View File

@@ -22,7 +22,7 @@ import android.os.Bundle
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -121,13 +121,9 @@ class StorageAppListModel(
): Flow<List<AppRecordWithSize>> = recordListFlow.filterItem { type.filter(it) } ): Flow<List<AppRecordWithSize>> = recordListFlow.filterItem { type.filter(it) }
@Composable @Composable
override fun getSummary(option: Int, record: AppRecordWithSize): State<String> { override fun getSummary(option: Int, record: AppRecordWithSize): () -> String {
val storageSummary = record.app.getStorageSummary() val storageSummary by record.app.getStorageSummary()
return remember { return { storageSummary }
derivedStateOf {
storageSummary.value
}
}
} }
@Composable @Composable

View File

@@ -22,10 +22,8 @@ import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.text.format.DateUtils import android.text.format.DateUtils
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import com.android.settings.R import com.android.settings.R
import com.android.settings.spa.development.UsageStatsListModel.SpinnerItem.Companion.toSpinnerItem import com.android.settings.spa.development.UsageStatsListModel.SpinnerItem.Companion.toSpinnerItem
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.widget.ui.SpinnerOption import com.android.settingslib.spa.widget.ui.SpinnerOption
import com.android.settingslib.spaprivileged.model.app.AppEntry import com.android.settingslib.spaprivileged.model.app.AppEntry
import com.android.settingslib.spaprivileged.model.app.AppListModel import com.android.settingslib.spaprivileged.model.app.AppListModel
@@ -55,7 +53,7 @@ class UsageStatsListModel(private val context: Context) : AppListModel<UsageStat
} }
override fun getSpinnerOptions(recordList: List<UsageStatsAppRecord>): List<SpinnerOption> = override fun getSpinnerOptions(recordList: List<UsageStatsAppRecord>): List<SpinnerOption> =
SpinnerItem.values().map { SpinnerItem.entries.map {
SpinnerOption( SpinnerOption(
id = it.ordinal, id = it.ordinal,
text = context.getString(it.stringResId), text = context.getString(it.stringResId),
@@ -77,7 +75,7 @@ class UsageStatsListModel(private val context: Context) : AppListModel<UsageStat
}.then(super.getComparator(option)) }.then(super.getComparator(option))
@Composable @Composable
override fun getSummary(option: Int, record: UsageStatsAppRecord): State<String>? { override fun getSummary(option: Int, record: UsageStatsAppRecord): (() -> String)? {
val usageStats = record.usageStats ?: return null val usageStats = record.usageStats ?: return null
val lastTimeUsed = DateUtils.formatSameDayTime( val lastTimeUsed = DateUtils.formatSameDayTime(
usageStats.lastTimeUsed, now, DateFormat.MEDIUM, DateFormat.MEDIUM usageStats.lastTimeUsed, now, DateFormat.MEDIUM, DateFormat.MEDIUM
@@ -85,7 +83,7 @@ class UsageStatsListModel(private val context: Context) : AppListModel<UsageStat
val lastTimeUsedLine = "${context.getString(R.string.last_time_used_label)}: $lastTimeUsed" val lastTimeUsedLine = "${context.getString(R.string.last_time_used_label)}: $lastTimeUsed"
val usageTime = DateUtils.formatElapsedTime(usageStats.totalTimeInForeground / 1000) val usageTime = DateUtils.formatElapsedTime(usageStats.totalTimeInForeground / 1000)
val usageTimeLine = "${context.getString(R.string.usage_time_label)}: $usageTime" val usageTimeLine = "${context.getString(R.string.usage_time_label)}: $usageTime"
return stateOf("$lastTimeUsedLine\n$usageTimeLine") return { "$lastTimeUsedLine\n$usageTimeLine" }
} }
private fun getUsageStats(): Map<String, UsageStats> { private fun getUsageStats(): Map<String, UsageStats> {
@@ -101,7 +99,7 @@ class UsageStatsListModel(private val context: Context) : AppListModel<UsageStat
AppName(R.string.usage_stats_sort_by_app_name); AppName(R.string.usage_stats_sort_by_app_name);
companion object { companion object {
fun Int.toSpinnerItem(): SpinnerItem = values()[this] fun Int.toSpinnerItem(): SpinnerItem = entries[this]
} }
} }
} }

View File

@@ -24,7 +24,6 @@ import androidx.compose.runtime.Composable
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import com.android.settings.core.SubSettingLauncher import com.android.settings.core.SubSettingLauncher
import com.android.settings.development.compat.PlatformCompatDashboard import com.android.settings.development.compat.PlatformCompatDashboard
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.framework.util.filterItem import com.android.settingslib.spa.framework.util.filterItem
import com.android.settingslib.spa.framework.util.mapItem import com.android.settingslib.spa.framework.util.mapItem
import com.android.settingslib.spaprivileged.model.app.AppListModel import com.android.settingslib.spaprivileged.model.app.AppListModel
@@ -53,8 +52,9 @@ class PlatformCompatAppListModel(
} }
@Composable @Composable
override fun getSummary(option: Int, record: PlatformCompatAppRecord) = override fun getSummary(option: Int, record: PlatformCompatAppRecord): () -> String = {
stateOf(record.app.packageName) record.app.packageName
}
@Composable @Composable
override fun AppListItemModel<PlatformCompatAppRecord>.AppItem() { override fun AppListItemModel<PlatformCompatAppRecord>.AppItem() {

View File

@@ -34,7 +34,6 @@ import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.scaffold.RegularScaffold
@@ -60,9 +59,10 @@ object NetworkAndInternetPageProvider : SettingsPageProvider {
fun buildInjectEntry(): SettingsEntryBuilder { fun buildInjectEntry(): SettingsEntryBuilder {
return SettingsEntryBuilder.createInject(owner = owner) return SettingsEntryBuilder.createInject(owner = owner)
.setUiLayoutFn { .setUiLayoutFn {
val summary = stringResource(getSummaryResId())
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource(R.string.network_dashboard_title) override val title = stringResource(R.string.network_dashboard_title)
override val summary = stringResource(getSummaryResId()).toState() override val summary = { summary }
override val onClick = navigator(name) override val onClick = navigator(name)
override val icon = @Composable { override val icon = @Composable {
SettingsIcon(imageVector = Icons.Outlined.Wifi) SettingsIcon(imageVector = Icons.Outlined.Wifi)

View File

@@ -23,7 +23,6 @@ import com.android.settings.R
import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.rememberContext import com.android.settingslib.spa.framework.compose.rememberContext
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.template.app.AppListPage import com.android.settingslib.spaprivileged.template.app.AppListPage
@@ -41,9 +40,10 @@ object AppListNotificationsPageProvider : SettingsPageProvider {
@Composable @Composable
fun EntryItem() { fun EntryItem() {
val summary = stringResource(R.string.app_notification_field_summary)
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource(R.string.app_notifications_title) override val title = stringResource(R.string.app_notifications_title)
override val summary = stringResource(R.string.app_notification_field_summary).toState() override val summary = { summary }
override val onClick = navigator(name) override val onClick = navigator(name)
}) })
} }

View File

@@ -27,7 +27,6 @@ import com.android.settings.R
import com.android.settings.applications.AppInfoBase import com.android.settings.applications.AppInfoBase
import com.android.settings.notification.app.AppNotificationSettings import com.android.settings.notification.app.AppNotificationSettings
import com.android.settings.spa.notification.SpinnerItem.Companion.toSpinnerItem import com.android.settings.spa.notification.SpinnerItem.Companion.toSpinnerItem
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.framework.util.asyncFilter import com.android.settingslib.spa.framework.util.asyncFilter
import com.android.settingslib.spa.framework.util.asyncForEach import com.android.settingslib.spa.framework.util.asyncForEach
import com.android.settingslib.spa.widget.ui.SpinnerOption import com.android.settingslib.spa.widget.ui.SpinnerOption
@@ -91,16 +90,17 @@ class AppNotificationsListModel(
}.then(super.getComparator(option)) }.then(super.getComparator(option))
@Composable @Composable
override fun getSummary(option: Int, record: AppNotificationsRecord) = record.sentState?.let { override fun getSummary(option: Int, record: AppNotificationsRecord): (() -> String)? =
record.sentState?.let {
when (option.toSpinnerItem()) { when (option.toSpinnerItem()) {
SpinnerItem.MostRecent -> stateOf(formatLastSent(it.lastSent)) SpinnerItem.MostRecent -> ({ formatLastSent(it.lastSent) })
SpinnerItem.MostFrequent -> stateOf(repository.calculateFrequencySummary(it.sentCount)) SpinnerItem.MostFrequent -> ({ repository.calculateFrequencySummary(it.sentCount) })
else -> null else -> null
} }
} }
override fun getSpinnerOptions(recordList: List<AppNotificationsRecord>): List<SpinnerOption> = override fun getSpinnerOptions(recordList: List<AppNotificationsRecord>): List<SpinnerOption> =
SpinnerItem.values().map { SpinnerItem.entries.map {
SpinnerOption( SpinnerOption(
id = it.ordinal, id = it.ordinal,
text = context.getString(it.stringResId), text = context.getString(it.stringResId),
@@ -145,6 +145,6 @@ private enum class SpinnerItem(val stringResId: Int) {
TurnedOff(R.string.filter_notif_blocked_apps); TurnedOff(R.string.filter_notif_blocked_apps);
companion object { companion object {
fun Int.toSpinnerItem(): SpinnerItem = values()[this] fun Int.toSpinnerItem(): SpinnerItem = entries[this]
} }
} }

View File

@@ -25,13 +25,12 @@ import com.android.settings.R
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.scaffold.RegularScaffold
import com.android.settingslib.spa.widget.ui.SettingsIcon import com.android.settingslib.spa.widget.ui.SettingsIcon
import com.android.settingslib.spa.framework.common.createSettingsPage
object NotificationMainPageProvider : SettingsPageProvider { object NotificationMainPageProvider : SettingsPageProvider {
override val name = "NotificationMain" override val name = "NotificationMain"
@@ -53,9 +52,10 @@ object NotificationMainPageProvider : SettingsPageProvider {
fun buildInjectEntry(): SettingsEntryBuilder { fun buildInjectEntry(): SettingsEntryBuilder {
return SettingsEntryBuilder.createInject(owner = owner) return SettingsEntryBuilder.createInject(owner = owner)
.setUiLayoutFn { .setUiLayoutFn {
val summary = stringResource(R.string.notification_dashboard_summary)
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource(R.string.configure_notification_settings) override val title = stringResource(R.string.configure_notification_settings)
override val summary = stringResource(R.string.notification_dashboard_summary).toState() override val summary = { summary }
override val onClick = navigator(name) override val onClick = navigator(name)
override val icon = @Composable { override val icon = @Composable {
SettingsIcon(imageVector = Icons.Outlined.Notifications) SettingsIcon(imageVector = Icons.Outlined.Notifications)

View File

@@ -26,7 +26,6 @@ import com.android.settings.R
import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.rememberContext import com.android.settingslib.spa.framework.compose.rememberContext
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.framework.theme.SettingsDimension import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
@@ -52,9 +51,10 @@ object AppLanguagesPageProvider : SettingsPageProvider {
@Composable @Composable
fun EntryItem() { fun EntryItem() {
val summary = stringResource(R.string.app_locale_picker_summary)
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource(R.string.app_locales_picker_menu_title) override val title = stringResource(R.string.app_locales_picker_menu_title)
override val summary = stringResource(R.string.app_locale_picker_summary).toState() override val summary = { summary }
override val onClick = navigator(name) override val onClick = navigator(name)
}) })
} }

View File

@@ -23,7 +23,7 @@ import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.UserHandle import android.os.UserHandle
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -79,12 +79,14 @@ class AppLanguagesListModel(private val context: Context) : AppListModel<AppLang
) = recordListFlow.filterItem { it.isAppLocaleSupported } ) = recordListFlow.filterItem { it.isAppLocaleSupported }
@Composable @Composable
override fun getSummary(option: Int, record: AppLanguagesRecord): State<String> = override fun getSummary(option: Int, record: AppLanguagesRecord): () -> String {
remember(record.app) { val summary by remember(record.app) {
flow { flow {
emit(getSummary(record.app)) emit(getSummary(record.app))
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
}.collectAsStateWithLifecycle(initialValue = stringResource(R.string.summary_placeholder)) }.collectAsStateWithLifecycle(initialValue = stringResource(R.string.summary_placeholder))
return { summary }
}
private fun getSummary(app: ApplicationInfo): String = private fun getSummary(app: ApplicationInfo): String =
AppLocaleDetails.getSummary(context, app).toString() AppLocaleDetails.getSummary(context, app).toString()

View File

@@ -24,7 +24,6 @@ import androidx.compose.ui.res.stringResource
import com.android.settings.R import com.android.settings.R
import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.scaffold.RegularScaffold
@@ -42,9 +41,10 @@ object LanguageAndInputPageProvider : SettingsPageProvider {
@Composable @Composable
fun EntryItem() { fun EntryItem() {
val summary = stringResource(R.string.language_settings)
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource(R.string.language_settings) override val title = stringResource(R.string.language_settings)
override val summary = stringResource(R.string.language_settings).toState() override val summary = { summary }
override val onClick = navigator(name) override val onClick = navigator(name)
override val icon = @Composable { override val icon = @Composable {
SettingsIcon(imageVector = Icons.Outlined.Language) SettingsIcon(imageVector = Icons.Outlined.Language)

View File

@@ -27,7 +27,6 @@ import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.scaffold.RegularScaffold
@@ -53,9 +52,10 @@ object SystemMainPageProvider : SettingsPageProvider {
fun buildInjectEntry(): SettingsEntryBuilder { fun buildInjectEntry(): SettingsEntryBuilder {
return SettingsEntryBuilder.createInject(owner = owner) return SettingsEntryBuilder.createInject(owner = owner)
.setUiLayoutFn { .setUiLayoutFn {
val summary = stringResource(R.string.system_dashboard_summary)
Preference(object : PreferenceModel { Preference(object : PreferenceModel {
override val title = stringResource(R.string.header_category_system) override val title = stringResource(R.string.header_category_system)
override val summary = stringResource(R.string.system_dashboard_summary).toState() override val summary = { summary }
override val onClick = navigator(name) override val onClick = navigator(name)
override val icon = @Composable { override val icon = @Composable {
SettingsIcon(imageVector = Icons.Outlined.Info) SettingsIcon(imageVector = Icons.Outlined.Info)

View File

@@ -21,7 +21,6 @@ import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import androidx.compose.runtime.SideEffect import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.State
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
@@ -146,12 +145,12 @@ class AllAppListTest {
fun allAppListModel_getSummary() { fun allAppListModel_getSummary() {
val listModel = AllAppListModel(context) { stateOf(SUMMARY) } val listModel = AllAppListModel(context) { stateOf(SUMMARY) }
lateinit var summaryState: State<String> lateinit var summary: () -> String
composeTestRule.setContent { composeTestRule.setContent {
summaryState = listModel.getSummary(option = 0, record = AppRecordWithSize(app = APP)) summary = listModel.getSummary(option = 0, record = AppRecordWithSize(app = APP))
} }
assertThat(summaryState.value).isEqualTo(SUMMARY) assertThat(summary()).isEqualTo(SUMMARY)
} }
@Test @Test
@@ -163,13 +162,13 @@ class AllAppListTest {
enabled = false enabled = false
} }
lateinit var summaryState: State<String> lateinit var summary: () -> String
composeTestRule.setContent { composeTestRule.setContent {
summaryState = summary =
listModel.getSummary(option = 0, record = AppRecordWithSize(app = disabledApp)) listModel.getSummary(option = 0, record = AppRecordWithSize(app = disabledApp))
} }
assertThat(summaryState.value).isEqualTo("$SUMMARY${System.lineSeparator()}Disabled") assertThat(summary()).isEqualTo("$SUMMARY${System.lineSeparator()}Disabled")
} }
@Test @Test
@@ -179,13 +178,13 @@ class AllAppListTest {
packageName = PACKAGE_NAME packageName = PACKAGE_NAME
} }
lateinit var summaryState: State<String> lateinit var summary: () -> String
composeTestRule.setContent { composeTestRule.setContent {
summaryState = summary =
listModel.getSummary(option = 0, record = AppRecordWithSize(app = notInstalledApp)) listModel.getSummary(option = 0, record = AppRecordWithSize(app = notInstalledApp))
} }
assertThat(summaryState.value) assertThat(summary())
.isEqualTo("$SUMMARY${System.lineSeparator()}Not installed for this user") .isEqualTo("$SUMMARY${System.lineSeparator()}Not installed for this user")
} }
@@ -207,7 +206,7 @@ class AllAppListTest {
AppListItemModel( AppListItemModel(
record = AppRecordWithSize(app = app), record = AppRecordWithSize(app = app),
label = LABEL, label = LABEL,
summary = stateOf(SUMMARY), summary = { SUMMARY },
).AppItem() ).AppItem()
} }
} }
@@ -224,13 +223,13 @@ class AllAppListTest {
isArchived = true isArchived = true
} }
lateinit var summaryState: State<String> lateinit var summary: () -> String
composeTestRule.setContent { composeTestRule.setContent {
summaryState = summary =
listModel.getSummary(option = 0, record = AppRecordWithSize(app = archivedApp)) listModel.getSummary(option = 0, record = AppRecordWithSize(app = archivedApp))
} }
assertThat(summaryState.value).isEqualTo(SUMMARY) assertThat(summary()).isEqualTo(SUMMARY)
} }
private fun getAppListInput(): AppListInput<AppRecordWithSize> { private fun getAppListInput(): AppListInput<AppRecordWithSize> {
@@ -252,7 +251,7 @@ class AllAppListTest {
AppListItemModel( AppListItemModel(
record = AppRecordWithSize(app = APP), record = AppRecordWithSize(app = APP),
label = LABEL, label = LABEL,
summary = stateOf(SUMMARY), summary = { SUMMARY },
).AppItem() ).AppItem()
} }
} }

View File

@@ -21,7 +21,6 @@ import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN import android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN
import android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET import android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET
import android.os.Build import android.os.Build
import androidx.compose.runtime.State
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
@@ -29,7 +28,6 @@ import androidx.compose.ui.test.performClick
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R import com.android.settings.R
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.testutils.FakeNavControllerWrapper import com.android.settingslib.spa.testutils.FakeNavControllerWrapper
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
import com.android.settingslib.spaprivileged.template.app.AppListItemModel import com.android.settingslib.spaprivileged.template.app.AppListItemModel
@@ -132,7 +130,7 @@ class UserAspectRatioAppsPageProviderTest {
AppListItemModel( AppListItemModel(
record = APP_RECORD_SUGGESTED, record = APP_RECORD_SUGGESTED,
label = LABEL, label = LABEL,
summary = stateOf(SUMMARY) summary = { SUMMARY }
).AppItem() ).AppItem()
} }
} }
@@ -141,23 +139,23 @@ class UserAspectRatioAppsPageProviderTest {
@Test @Test
fun aspectRatioAppListModel_getSummaryDefault() { fun aspectRatioAppListModel_getSummaryDefault() {
val summaryState = setSummaryState(USER_MIN_ASPECT_RATIO_UNSET) val summary = getSummary(USER_MIN_ASPECT_RATIO_UNSET)
assertThat(summaryState.value)
.isEqualTo(context.getString(R.string.user_aspect_ratio_app_default)) assertThat(summary).isEqualTo(context.getString(R.string.user_aspect_ratio_app_default))
} }
@Test @Test
fun aspectRatioAppListModel_getSummaryWhenSplitScreen() { fun aspectRatioAppListModel_getSummaryWhenSplitScreen() {
val summaryState = setSummaryState(USER_MIN_ASPECT_RATIO_SPLIT_SCREEN) val summary = getSummary(USER_MIN_ASPECT_RATIO_SPLIT_SCREEN)
assertThat(summaryState.value)
.isEqualTo(context.getString(R.string.user_aspect_ratio_half_screen)) assertThat(summary).isEqualTo(context.getString(R.string.user_aspect_ratio_half_screen))
} }
private fun setSummaryState(userOverride: Int): State<String> { private fun getSummary(userOverride: Int): String {
val listModel = UserAspectRatioAppListModel(context) val listModel = UserAspectRatioAppListModel(context)
lateinit var summaryState: State<String> lateinit var summary: () -> String
composeTestRule.setContent { composeTestRule.setContent {
summaryState = listModel.getSummary(option = 0, summary = listModel.getSummary(option = 0,
record = UserAspectRatioAppListItemModel( record = UserAspectRatioAppListItemModel(
app = APP, app = APP,
userOverride = userOverride, userOverride = userOverride,
@@ -165,7 +163,7 @@ class UserAspectRatioAppsPageProviderTest {
canDisplay = true, canDisplay = true,
)) ))
} }
return summaryState return summary()
} }

View File

@@ -29,7 +29,6 @@ import androidx.compose.ui.test.performClick
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R import com.android.settings.R
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.testutils.FakeNavControllerWrapper import com.android.settingslib.spa.testutils.FakeNavControllerWrapper
import com.android.settingslib.spaprivileged.template.app.AppListItemModel import com.android.settingslib.spaprivileged.template.app.AppListItemModel
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
@@ -244,7 +243,7 @@ class BackgroundInstalledAppsPageProviderTest {
app = APP, app = APP,
dateOfInstall = TEST_FIRST_INSTALL_TIME), dateOfInstall = TEST_FIRST_INSTALL_TIME),
label = TEST_LABEL, label = TEST_LABEL,
summary = stateOf(TEST_SUMMARY), summary = { TEST_SUMMARY },
).AppItem() ).AppItem()
} }
} }

View File

@@ -20,7 +20,6 @@ import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.pm.PackageManager.PackageInfoFlags import android.content.pm.PackageManager.PackageInfoFlags
import androidx.compose.runtime.State
import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -79,20 +78,20 @@ class PlatformCompatAppListModelTest {
@Test @Test
fun getSummary() = runTest { fun getSummary() = runTest {
val summaryState = getSummaryState(APP) val summary = getSummary(APP)
assertThat(summaryState.value).isEqualTo(PACKAGE_NAME) assertThat(summary).isEqualTo(PACKAGE_NAME)
} }
private fun getSummaryState(app: ApplicationInfo): State<String> { private fun getSummary(app: ApplicationInfo): String {
lateinit var summary: State<String> lateinit var summary: () -> String
composeTestRule.setContent { composeTestRule.setContent {
summary = listModel.getSummary( summary = listModel.getSummary(
option = 0, option = 0,
record = PlatformCompatAppRecord(app), record = PlatformCompatAppRecord(app),
) )
} }
return summary return summary()
} }
private companion object { private companion object {