diff --git a/src/com/android/settings/spa/app/AllAppList.kt b/src/com/android/settings/spa/app/AllAppList.kt index cd116c17729..05f77ed05f7 100644 --- a/src/com/android/settings/spa/app/AllAppList.kt +++ b/src/com/android/settings/spa/app/AllAppList.kt @@ -36,6 +36,7 @@ import com.android.settingslib.spaprivileged.model.app.AppRecord import com.android.settingslib.spaprivileged.template.app.AppList import com.android.settingslib.spaprivileged.template.app.AppListInput import com.android.settingslib.spaprivileged.template.app.AppListItem +import com.android.settingslib.spaprivileged.template.app.AppListItemModel import com.android.settingslib.spaprivileged.template.app.AppListPage import com.android.settingslib.spaprivileged.template.app.getStorageSize import kotlinx.coroutines.flow.Flow @@ -70,9 +71,7 @@ fun AllAppListPage( showInstantApps = true, moreOptions = { ResetAppPreferences(resetAppDialogPresenter::open) }, appList = appList, - ) { - AppListItem(onClick = AppInfoSettingsProvider.navigator(app = record.app)) - } + ) } data class AppRecordWithSize( @@ -88,4 +87,9 @@ class AllAppListModel( @Composable override fun getSummary(option: Int, record: AppRecordWithSize) = record.app.getSummary() + + @Composable + override fun AppListItemModel.AppItem() { + AppListItem(onClick = AppInfoSettingsProvider.navigator(app = record.app)) + } } diff --git a/src/com/android/settings/spa/development/UsageStats.kt b/src/com/android/settings/spa/development/UsageStats.kt index d98ef599f9c..b681d7579de 100644 --- a/src/com/android/settings/spa/development/UsageStats.kt +++ b/src/com/android/settings/spa/development/UsageStats.kt @@ -21,11 +21,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settingslib.spa.framework.common.SettingsPageProvider -import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.rememberContext -import com.android.settingslib.spa.widget.preference.Preference -import com.android.settingslib.spa.widget.preference.PreferenceModel -import com.android.settingslib.spaprivileged.template.app.AppListItem import com.android.settingslib.spaprivileged.template.app.AppListPage object UsageStatsPageProvider : SettingsPageProvider { @@ -37,14 +33,6 @@ object UsageStatsPageProvider : SettingsPageProvider { title = stringResource(R.string.testing_usage_stats), listModel = rememberContext(::UsageStatsListModel), primaryUserOnly = true, - ) { AppListItem {} } - } - - @Composable - fun EntryItem() { - Preference(object : PreferenceModel { - override val title = stringResource(R.string.testing_usage_stats) - override val onClick = navigator(name) - }) + ) } } diff --git a/src/com/android/settings/spa/notification/AppListNotifications.kt b/src/com/android/settings/spa/notification/AppListNotifications.kt index 0e6c5e2d6da..c1e5d643639 100644 --- a/src/com/android/settings/spa/notification/AppListNotifications.kt +++ b/src/com/android/settings/spa/notification/AppListNotifications.kt @@ -16,27 +16,17 @@ package com.android.settings.spa.notification -import android.app.settings.SettingsEnums -import android.content.Context -import android.content.pm.ApplicationInfo import android.os.Bundle import androidx.compose.runtime.Composable -import androidx.compose.runtime.livedata.observeAsState -import androidx.compose.runtime.produceState -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import com.android.settings.R -import com.android.settings.applications.AppInfoBase -import com.android.settings.notification.app.AppNotificationSettings import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.compose.navigator 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.PreferenceModel -import com.android.settingslib.spaprivileged.template.app.AppListItemModel import com.android.settingslib.spaprivileged.template.app.AppListPage -import com.android.settingslib.spaprivileged.template.app.AppListSwitchItem object AppListNotificationsPageProvider : SettingsPageProvider { override val name = "AppListNotifications" @@ -46,7 +36,7 @@ object AppListNotificationsPageProvider : SettingsPageProvider { AppListPage( title = stringResource(R.string.app_notifications_title), listModel = rememberContext(::AppNotificationsListModel), - ) { AppNotificationsItem() } + ) } @Composable @@ -58,32 +48,3 @@ object AppListNotificationsPageProvider : SettingsPageProvider { }) } } - -@Composable -private fun AppListItemModel.AppNotificationsItem() { - val appNotificationsRepository = rememberContext(::AppNotificationRepository) - val context = LocalContext.current - AppListSwitchItem( - onClick = { - navigateToAppNotificationSettings( - context = context, - app = record.app, - ) - }, - checked = record.controller.isEnabled.observeAsState(), - changeable = produceState(initialValue = false) { - value = appNotificationsRepository.isChangeable(record.app) - }, - onCheckedChange = record.controller::setEnabled, - ) -} - -private fun navigateToAppNotificationSettings(context: Context, app: ApplicationInfo) { - AppInfoBase.startAppInfoFragment( - AppNotificationSettings::class.java, - context.getString(R.string.notifications_title), - app, - context, - SettingsEnums.MANAGE_APPLICATIONS_NOTIFICATIONS, - ) -} diff --git a/src/com/android/settings/spa/notification/AppNotificationsListModel.kt b/src/com/android/settings/spa/notification/AppNotificationsListModel.kt index ff951fce144..c7baa033604 100644 --- a/src/com/android/settings/spa/notification/AppNotificationsListModel.kt +++ b/src/com/android/settings/spa/notification/AppNotificationsListModel.kt @@ -16,11 +16,16 @@ package com.android.settings.spa.notification +import android.app.settings.SettingsEnums import android.content.Context import android.content.pm.ApplicationInfo import android.icu.text.RelativeDateTimeFormatter import androidx.compose.runtime.Composable +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.produceState import com.android.settings.R +import com.android.settings.applications.AppInfoBase +import com.android.settings.notification.app.AppNotificationSettings 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 @@ -28,6 +33,8 @@ import com.android.settingslib.spa.framework.util.asyncForEach import com.android.settingslib.spaprivileged.model.app.AppEntry import com.android.settingslib.spaprivileged.model.app.AppListModel import com.android.settingslib.spaprivileged.model.app.AppRecord +import com.android.settingslib.spaprivileged.template.app.AppListItemModel +import com.android.settingslib.spaprivileged.template.app.AppListSwitchItem import com.android.settingslib.utils.StringUtil import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine @@ -114,6 +121,28 @@ class AppNotificationsListModel( ) } } + + @Composable + override fun AppListItemModel.AppItem() { + AppListSwitchItem( + onClick = { navigateToAppNotificationSettings(app = record.app) }, + checked = record.controller.isEnabled.observeAsState(), + changeable = produceState(initialValue = false) { + value = repository.isChangeable(record.app) + }, + onCheckedChange = record.controller::setEnabled, + ) + } + + private fun navigateToAppNotificationSettings(app: ApplicationInfo) { + AppInfoBase.startAppInfoFragment( + AppNotificationSettings::class.java, + context.getString(R.string.notifications_title), + app, + context, + SettingsEnums.MANAGE_APPLICATIONS_NOTIFICATIONS, + ) + } } private enum class SpinnerItem(val stringResId: Int) { diff --git a/src/com/android/settings/spa/system/AppLanguages.kt b/src/com/android/settings/spa/system/AppLanguages.kt index bcb65352a27..f53a63d8be8 100644 --- a/src/com/android/settings/spa/system/AppLanguages.kt +++ b/src/com/android/settings/spa/system/AppLanguages.kt @@ -16,17 +16,13 @@ package com.android.settings.spa.system -import android.content.Intent -import android.net.Uri import android.os.Bundle import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import com.android.settings.R -import com.android.settings.localepicker.AppLocalePickerActivity import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.rememberContext @@ -35,8 +31,6 @@ import com.android.settingslib.spa.framework.theme.SettingsDimension 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.spaprivileged.template.app.AppListItem -import com.android.settingslib.spaprivileged.template.app.AppListItemModel import com.android.settingslib.spaprivileged.template.app.AppListPage object AppLanguagesPageProvider : SettingsPageProvider { @@ -52,7 +46,7 @@ object AppLanguagesPageProvider : SettingsPageProvider { SettingsBody(stringResource(R.string.desc_app_locale_selection_supported)) } }, - ) { AppLanguageItem() } + ) } @Composable @@ -64,15 +58,3 @@ object AppLanguagesPageProvider : SettingsPageProvider { }) } } - -@Composable -private fun AppListItemModel.AppLanguageItem() { - val context = LocalContext.current - AppListItem { - val intent = Intent(context, AppLocalePickerActivity::class.java).apply { - data = Uri.parse("package:${record.app.packageName}") - putExtra("uid", record.app.uid) - } - context.startActivity(intent) - } -} diff --git a/src/com/android/settings/spa/system/AppLanguagesListModel.kt b/src/com/android/settings/spa/system/AppLanguagesListModel.kt index eea72f2ce0e..4aa4c7a5700 100644 --- a/src/com/android/settings/spa/system/AppLanguagesListModel.kt +++ b/src/com/android/settings/spa/system/AppLanguagesListModel.kt @@ -17,8 +17,10 @@ package com.android.settings.spa.system import android.content.Context +import android.content.Intent import android.content.pm.ApplicationInfo import android.content.pm.PackageManager +import android.net.Uri import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.remember @@ -28,56 +30,73 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.settings.R import com.android.settings.applications.AppLocaleUtil import com.android.settings.applications.appinfo.AppLocaleDetails +import com.android.settings.localepicker.AppLocalePickerActivity +import com.android.settingslib.spa.framework.util.filterItem import com.android.settingslib.spaprivileged.model.app.AppListModel import com.android.settingslib.spaprivileged.model.app.AppRecord +import com.android.settingslib.spaprivileged.template.app.AppListItem +import com.android.settingslib.spaprivileged.template.app.AppListItemModel +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map data class AppLanguagesRecord( override val app: ApplicationInfo, - val isAppLocaleSupported: Boolean + val isAppLocaleSupported: Boolean, ) : AppRecord class AppLanguagesListModel(private val context: Context) : AppListModel { - private val now = System.currentTimeMillis() private val packageManager = context.packageManager override fun transform(userIdFlow: Flow, appListFlow: Flow>) = userIdFlow.map { userId -> packageManager.queryIntentActivitiesAsUser( - AppLocaleUtil.LAUNCHER_ENTRY_INTENT, - PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA.toLong()), - userId, - ) + AppLocaleUtil.LAUNCHER_ENTRY_INTENT, + PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA.toLong()), + userId, + ) }.combine(appListFlow) { resolveInfos, appList -> appList.map { app -> - AppLanguagesRecord(app, - AppLocaleUtil.canDisplayLocaleUi(context, - app, resolveInfos)) + AppLanguagesRecord( + app = app, + isAppLocaleSupported = AppLocaleUtil.canDisplayLocaleUi( + context, app, resolveInfos + ), + ) } } override fun filter( userIdFlow: Flow, option: Int, - recordListFlow: Flow> - ) = recordListFlow.map { recordList -> - recordList.filter { it.isAppLocaleSupported } - } + recordListFlow: Flow>, + ) = recordListFlow.filterItem { it.isAppLocaleSupported } @OptIn(ExperimentalLifecycleComposeApi::class) @Composable - override fun getSummary(option: Int, record: AppLanguagesRecord): State? = + override fun getSummary(option: Int, record: AppLanguagesRecord): State = remember(record.app) { flow { emit(getSummary(record.app)) - } + }.flowOn(Dispatchers.IO) }.collectAsStateWithLifecycle(initialValue = stringResource(R.string.summary_placeholder)) private fun getSummary(app: ApplicationInfo): String = AppLocaleDetails.getAppDefaultLocale(context, app.packageName)?.let { AppLocaleDetails.getSummary(context, app).toString() } ?: context.getString(R.string.preference_of_system_locale_summary) -} \ No newline at end of file + + @Composable + override fun AppListItemModel.AppItem() { + AppListItem { + val intent = Intent(context, AppLocalePickerActivity::class.java).apply { + data = Uri.parse("package:${record.app.packageName}") + this.putExtra("uid", record.app.uid) + } + context.startActivity(intent) + } + } +} diff --git a/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt index 1a5f3ab36a6..b76791298fd 100644 --- a/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt @@ -156,13 +156,13 @@ class AllAppListTest { private fun setItemContent() { composeTestRule.setContent { - AllAppListPage { - fakeNavControllerWrapper.Wrapper { + fakeNavControllerWrapper.Wrapper { + with(AllAppListModel()) { AppListItemModel( record = AppRecordWithSize(app = APP), label = LABEL, summary = stateOf(SUMMARY), - ).appItem() + ).AppItem() } } }