• 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.app.appinfo
18 
19 import android.content.Context
20 import android.content.pm.ApplicationInfo
21 import android.content.pm.PackageManager.OnPermissionsChangedListener
22 import android.icu.text.ListFormatter
23 import androidx.compose.runtime.Composable
24 import androidx.compose.runtime.remember
25 import androidx.compose.ui.platform.LocalContext
26 import androidx.lifecycle.LiveData
27 import com.android.settings.R
28 import com.android.settingslib.applications.PermissionsSummaryHelper
29 import com.android.settingslib.applications.PermissionsSummaryHelper.PermissionsResultCallback
30 import com.android.settingslib.spa.framework.util.formatString
31 import com.android.settingslib.spaprivileged.framework.common.asUser
32 import com.android.settingslib.spaprivileged.model.app.userHandle
33 
34 data class AppPermissionSummaryState(
35     val summary: String,
36     val enabled: Boolean,
37 )
38 
39 @Composable
40 fun rememberAppPermissionSummary(app: ApplicationInfo): AppPermissionSummaryLiveData {
41     val context = LocalContext.current
42     return remember { AppPermissionSummaryLiveData(context, app) }
43 }
44 
45 class AppPermissionSummaryLiveData(
46     private val context: Context,
47     private val app: ApplicationInfo,
48 ) : LiveData<AppPermissionSummaryState>() {
49     private val userContext = context.asUser(app.userHandle)
50     private val userPackageManager = userContext.packageManager
51 
uidnull52     private val onPermissionsChangedListener = OnPermissionsChangedListener { uid ->
53         if (uid == app.uid) update()
54     }
55 
onActivenull56     override fun onActive() {
57         userPackageManager.addOnPermissionsChangeListener(onPermissionsChangedListener)
58         update()
59     }
60 
onInactivenull61     override fun onInactive() {
62         userPackageManager.removeOnPermissionsChangeListener(onPermissionsChangedListener)
63     }
64 
updatenull65     private fun update() {
66         PermissionsSummaryHelper.getPermissionSummary(
67             userContext, app.packageName, permissionsCallback
68         )
69     }
70 
71     private val permissionsCallback = object : PermissionsResultCallback {
onPermissionSummaryResultnull72         override fun onPermissionSummaryResult(
73             requestedPermissionCount: Int,
74             additionalGrantedPermissionCount: Int,
75             grantedGroupLabels: List<CharSequence>,
76         ) {
77             if (requestedPermissionCount == 0) {
78                 postValue(noPermissionRequestedState())
79                 return
80             }
81             val labels = getDisplayLabels(additionalGrantedPermissionCount, grantedGroupLabels)
82             val summary = if (labels.isNotEmpty()) {
83                 ListFormatter.getInstance().format(labels)
84             } else {
85                 context.getString(R.string.runtime_permissions_summary_no_permissions_granted)
86             }
87             postValue(AppPermissionSummaryState(summary = summary, enabled = true))
88         }
89     }
90 
noPermissionRequestedStatenull91     private fun noPermissionRequestedState() = AppPermissionSummaryState(
92         summary = context.getString(R.string.runtime_permissions_summary_no_permissions_requested),
93         enabled = false,
94     )
95 
96     private fun getDisplayLabels(
97         additionalGrantedPermissionCount: Int,
98         grantedGroupLabels: List<CharSequence>,
99     ): List<CharSequence> = when (additionalGrantedPermissionCount) {
100         0 -> grantedGroupLabels
101         else -> {
102             grantedGroupLabels +
103                 // N additional permissions.
104                 context.formatString(
105                     R.string.runtime_permissions_additional_count,
106                     "count" to additionalGrantedPermissionCount,
107                 )
108         }
109     }
110 }
111