1 /* <lambda>null2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.spa.system 18 19 import android.app.settings.SettingsEnums 20 import android.content.Context 21 import android.content.Intent 22 import android.content.pm.ApplicationInfo 23 import android.content.pm.PackageManager 24 import android.net.Uri 25 import android.os.Bundle 26 import android.os.UserHandle 27 import androidx.compose.runtime.Composable 28 import androidx.compose.runtime.getValue 29 import androidx.compose.runtime.remember 30 import androidx.compose.ui.res.stringResource 31 import androidx.lifecycle.compose.collectAsStateWithLifecycle 32 import com.android.settings.R 33 import com.android.settings.applications.AppLocaleUtil 34 import com.android.settings.applications.appinfo.AppLocaleDetails 35 import com.android.settings.core.SubSettingLauncher 36 import com.android.settings.localepicker.AppLocalePickerActivity 37 import com.android.settings.localepicker.AppLocalePickerFragment 38 import com.android.settingslib.spa.framework.util.filterItem 39 import com.android.settingslib.spaprivileged.framework.common.asUser 40 import com.android.settingslib.spaprivileged.model.app.AppListModel 41 import com.android.settingslib.spaprivileged.model.app.AppRecord 42 import com.android.settingslib.spaprivileged.model.app.userHandle 43 import com.android.settingslib.spaprivileged.template.app.AppListItem 44 import com.android.settingslib.spaprivileged.template.app.AppListItemModel 45 import com.android.settingslib.widget.SettingsThemeHelper 46 import kotlinx.coroutines.Dispatchers 47 import kotlinx.coroutines.flow.Flow 48 import kotlinx.coroutines.flow.combine 49 import kotlinx.coroutines.flow.flow 50 import kotlinx.coroutines.flow.flowOn 51 import kotlinx.coroutines.flow.map 52 53 data class AppLanguagesRecord( 54 override val app: ApplicationInfo, 55 val isAppLocaleSupported: Boolean, 56 ) : AppRecord 57 58 class AppLanguagesListModel(private val context: Context) : AppListModel<AppLanguagesRecord> { 59 private val packageManager = context.packageManager 60 61 override fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>) = 62 userIdFlow.map { userId -> 63 userId to packageManager.queryIntentActivitiesAsUser( 64 AppLocaleUtil.LAUNCHER_ENTRY_INTENT, 65 PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA.toLong()), 66 userId, 67 ) 68 }.combine(appListFlow) { (userId, resolveInfos), appList -> 69 val userContext = context.asUser(UserHandle.of(userId)) 70 appList.map { app -> 71 AppLanguagesRecord( 72 app = app, 73 isAppLocaleSupported = AppLocaleUtil.canDisplayLocaleUi( 74 userContext, app, resolveInfos 75 ), 76 ) 77 } 78 } 79 80 override fun filter( 81 userIdFlow: Flow<Int>, 82 option: Int, 83 recordListFlow: Flow<List<AppLanguagesRecord>>, 84 ) = recordListFlow.filterItem { it.isAppLocaleSupported } 85 86 @Composable 87 override fun getSummary(option: Int, record: AppLanguagesRecord): () -> String { 88 val summary by remember(record.app) { 89 flow { 90 emit(getSummary(record.app)) 91 }.flowOn(Dispatchers.IO) 92 }.collectAsStateWithLifecycle(initialValue = stringResource(R.string.summary_placeholder)) 93 return { summary } 94 } 95 96 private fun getSummary(app: ApplicationInfo): String = 97 AppLocaleDetails.getSummary(context, app).toString() 98 99 @Composable 100 override fun AppListItemModel<AppLanguagesRecord>.AppItem() { 101 AppListItem { 102 if (SettingsThemeHelper.isExpressiveTheme(context)) { 103 val extra = Bundle() 104 extra.putString(AppLocalePickerFragment.ARG_PACKAGE_NAME, record.app.packageName) 105 extra.putInt(AppLocalePickerFragment.ARG_PACKAGE_UID, context.userId) 106 SubSettingLauncher(context) 107 .setDestination(AppLocalePickerFragment::class.java.canonicalName) 108 .setTitleText(context.getString(R.string.app_locale_picker_title)) 109 .setSourceMetricsCategory(SettingsEnums.APPS_LOCALE_LIST) 110 .setArguments(extra) 111 .setUserHandle(record.app.userHandle) 112 .launch() 113 } else { 114 val intent = Intent(context, AppLocalePickerActivity::class.java).apply { 115 data = Uri.parse("package:${record.app.packageName}") 116 } 117 context.startActivityAsUser(intent, record.app.userHandle) 118 } 119 } 120 } 121 } 122