Move AppItem into AppListModel

Follows the api changes in Spa privileged lib.

Bug: 260660819
Test: Unit test
Test: Manually with Settings
Change-Id: Ieec1035070cc532eedcd1511c5b347e04099a9fb
This commit is contained in:
Chaohui Wang
2022-12-15 12:30:44 +08:00
parent c8b31a5170
commit 1445d985bb
7 changed files with 78 additions and 95 deletions

View File

@@ -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<AppRecordWithSize>.AppItem() {
AppListItem(onClick = AppInfoSettingsProvider.navigator(app = record.app))
}
}

View File

@@ -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)
})
)
}
}

View File

@@ -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<AppNotificationsRecord>.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,
)
}

View File

@@ -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<AppNotificationsRecord>.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) {

View File

@@ -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<AppLanguagesRecord>.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)
}
}

View File

@@ -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<AppLanguagesRecord> {
private val now = System.currentTimeMillis()
private val packageManager = context.packageManager
override fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>) =
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<Int>,
option: Int,
recordListFlow: Flow<List<AppLanguagesRecord>>
) = recordListFlow.map { recordList ->
recordList.filter { it.isAppLocaleSupported }
}
recordListFlow: Flow<List<AppLanguagesRecord>>,
) = recordListFlow.filterItem { it.isAppLocaleSupported }
@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
override fun getSummary(option: Int, record: AppLanguagesRecord): State<String>? =
override fun getSummary(option: Int, record: AppLanguagesRecord): State<String> =
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)
}
@Composable
override fun AppListItemModel<AppLanguagesRecord>.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)
}
}
}

View File

@@ -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()
}
}
}