1 /*
<lambda>null2  * Copyright (C) 2024 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.app.appinfo
18 
19 import android.content.Context
20 import android.content.pm.ApplicationInfo
21 import android.icu.text.ListFormatter
22 import androidx.compose.runtime.Composable
23 import androidx.compose.runtime.remember
24 import androidx.compose.ui.platform.LocalContext
25 import com.android.settings.R
26 import com.android.settingslib.applications.PermissionsSummaryHelper
27 import com.android.settingslib.spa.framework.util.formatString
28 import com.android.settingslib.spaprivileged.framework.common.asUser
29 import com.android.settingslib.spaprivileged.model.app.permissionsChangedFlow
30 import com.android.settingslib.spaprivileged.model.app.userHandle
31 import kotlin.coroutines.resume
32 import kotlinx.coroutines.Dispatchers
33 import kotlinx.coroutines.flow.Flow
34 import kotlinx.coroutines.flow.flowOn
35 import kotlinx.coroutines.flow.map
36 import kotlinx.coroutines.suspendCancellableCoroutine
37 
38 data class AppPermissionSummaryState(
39     val summary: String,
40     val enabled: Boolean,
41 )
42 
43 @Composable
44 fun rememberAppPermissionSummary(app: ApplicationInfo): Flow<AppPermissionSummaryState> {
45     val context = LocalContext.current
46     return remember(app) { AppPermissionSummaryRepository(context, app).flow }
47 }
48 
49 class AppPermissionSummaryRepository(
50     private val context: Context,
51     private val app: ApplicationInfo,
52 ) {
53     private val userContext = context.asUser(app.userHandle)
54 
55     val flow = context.permissionsChangedFlow(app)
<lambda>null56         .map { getPermissionSummary() }
57         .flowOn(Dispatchers.Default)
58 
getPermissionSummarynull59     private suspend fun getPermissionSummary() = suspendCancellableCoroutine { continuation ->
60         PermissionsSummaryHelper.getPermissionSummary(
61             userContext,
62             app.packageName,
63         ) { requestedPermissionCount: Int,
64             additionalGrantedPermissionCount: Int,
65             grantedGroupLabels: List<CharSequence> ->
66             val summaryState = if (requestedPermissionCount == 0) {
67                 noPermissionRequestedState()
68             } else {
69                 val labels = getDisplayLabels(additionalGrantedPermissionCount, grantedGroupLabels)
70                 val summary = if (labels.isNotEmpty()) {
71                     ListFormatter.getInstance().format(labels)
72                 } else {
73                     context.getString(R.string.runtime_permissions_summary_no_permissions_granted)
74                 }
75                 AppPermissionSummaryState(summary = summary, enabled = true)
76             }
77             continuation.resume(summaryState)
78         }
79     }
80 
noPermissionRequestedStatenull81     private fun noPermissionRequestedState() = AppPermissionSummaryState(
82         summary = context.getString(R.string.runtime_permissions_summary_no_permissions_requested),
83         enabled = false,
84     )
85 
86     private fun getDisplayLabels(
87         additionalGrantedPermissionCount: Int,
88         grantedGroupLabels: List<CharSequence>,
89     ): List<CharSequence> = if (additionalGrantedPermissionCount == 0) {
90         grantedGroupLabels
91     } else {
92         grantedGroupLabels +
93             // N additional permissions.
94             context.formatString(
95                 R.string.runtime_permissions_additional_count,
96                 "count" to additionalGrantedPermissionCount,
97             )
98     }
99 }
100