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.content.Context 20 import android.content.Intent 21 import android.content.pm.ApplicationInfo 22 import android.content.pm.PackageManager 23 import android.net.Uri 24 import android.os.UserHandle 25 import androidx.compose.runtime.Composable 26 import androidx.compose.runtime.getValue 27 import androidx.compose.runtime.remember 28 import androidx.compose.ui.res.stringResource 29 import androidx.lifecycle.compose.collectAsStateWithLifecycle 30 import com.android.settings.R 31 import com.android.settings.applications.AppLocaleUtil 32 import com.android.settings.applications.appinfo.AppLocaleDetails 33 import com.android.settings.localepicker.AppLocalePickerActivity 34 import com.android.settingslib.spa.framework.util.filterItem 35 import com.android.settingslib.spaprivileged.framework.common.asUser 36 import com.android.settingslib.spaprivileged.model.app.AppListModel 37 import com.android.settingslib.spaprivileged.model.app.AppRecord 38 import com.android.settingslib.spaprivileged.model.app.userHandle 39 import com.android.settingslib.spaprivileged.template.app.AppListItem 40 import com.android.settingslib.spaprivileged.template.app.AppListItemModel 41 import kotlinx.coroutines.Dispatchers 42 import kotlinx.coroutines.flow.Flow 43 import kotlinx.coroutines.flow.combine 44 import kotlinx.coroutines.flow.flow 45 import kotlinx.coroutines.flow.flowOn 46 import kotlinx.coroutines.flow.map 47 48 data class AppLanguagesRecord( 49 override val app: ApplicationInfo, 50 val isAppLocaleSupported: Boolean, 51 ) : AppRecord 52 53 class AppLanguagesListModel(private val context: Context) : AppListModel<AppLanguagesRecord> { 54 private val packageManager = context.packageManager 55 56 override fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>) = 57 userIdFlow.map { userId -> 58 userId to packageManager.queryIntentActivitiesAsUser( 59 AppLocaleUtil.LAUNCHER_ENTRY_INTENT, 60 PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA.toLong()), 61 userId, 62 ) 63 }.combine(appListFlow) { (userId, resolveInfos), appList -> 64 val userContext = context.asUser(UserHandle.of(userId)) 65 appList.map { app -> 66 AppLanguagesRecord( 67 app = app, 68 isAppLocaleSupported = AppLocaleUtil.canDisplayLocaleUi( 69 userContext, app, resolveInfos 70 ), 71 ) 72 } 73 } 74 75 override fun filter( 76 userIdFlow: Flow<Int>, 77 option: Int, 78 recordListFlow: Flow<List<AppLanguagesRecord>>, 79 ) = recordListFlow.filterItem { it.isAppLocaleSupported } 80 81 @Composable 82 override fun getSummary(option: Int, record: AppLanguagesRecord): () -> String { 83 val summary by remember(record.app) { 84 flow { 85 emit(getSummary(record.app)) 86 }.flowOn(Dispatchers.IO) 87 }.collectAsStateWithLifecycle(initialValue = stringResource(R.string.summary_placeholder)) 88 return { summary } 89 } 90 91 private fun getSummary(app: ApplicationInfo): String = 92 AppLocaleDetails.getSummary(context, app).toString() 93 94 @Composable 95 override fun AppListItemModel<AppLanguagesRecord>.AppItem() { 96 AppListItem { 97 val intent = Intent(context, AppLocalePickerActivity::class.java).apply { 98 data = Uri.parse("package:${record.app.packageName}") 99 } 100 context.startActivityAsUser(intent, record.app.userHandle) 101 } 102 } 103 } 104