• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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