1 /* <lambda>null2 * Copyright (C) 2019 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.permissioncontroller.permission.data 18 19 import android.app.Application 20 import android.os.UserHandle 21 import androidx.lifecycle.LiveData 22 import com.android.permissioncontroller.permission.model.livedatatypes.AppPermGroupUiInfo 23 import com.android.permissioncontroller.permission.model.livedatatypes.PermGroupPackagesUiInfo 24 25 /** 26 * A LiveData which tracks all app permission groups for a set of permission groups, either platform 27 * or custom, as well as the UI information related to each app permission group, and the permission 28 * group as a whole. 29 * 30 * @param app The current application 31 */ 32 class PermGroupsPackagesUiInfoLiveData( 33 private val app: Application, 34 groupNamesLiveData: LiveData<List<String>> 35 ) : SmartUpdateMediatorLiveData< 36 @kotlin.jvm.JvmSuppressWildcards Map<String, PermGroupPackagesUiInfo?>>() { 37 38 /** 39 * Map<permission group name, PermGroupUiLiveDatas> 40 */ 41 private val permGroupPackagesLiveDatas = mutableMapOf<String, 42 SinglePermGroupPackagesUiInfoLiveData>() 43 private val allPackageData = mutableMapOf<String, PermGroupPackagesUiInfo?>() 44 45 private lateinit var groupNames: List<String> 46 47 init { 48 addSource(groupNamesLiveData) { 49 groupNames = it ?: emptyList() 50 updateIfActive() 51 getPermGroupPackageLiveDatas() 52 } 53 } 54 55 private fun getPermGroupPackageLiveDatas() { 56 val getLiveData = { groupName: String -> SinglePermGroupPackagesUiInfoLiveData[groupName] } 57 setSourcesToDifference(groupNames, permGroupPackagesLiveDatas, getLiveData) 58 } 59 60 private fun getNonSystemTotal(uiInfo: Map<Pair<String, UserHandle>, AppPermGroupUiInfo>): Int { 61 var shownNonSystem = 0 62 for ((_, appPermGroup) in uiInfo) { 63 if (appPermGroup.shouldShow && !appPermGroup.isSystem) { 64 shownNonSystem++ 65 } 66 } 67 return shownNonSystem 68 } 69 70 private fun getNonSystemGranted( 71 uiInfo: Map<Pair<String, UserHandle>, AppPermGroupUiInfo> 72 ): Int { 73 var granted = 0 74 for ((_, appPermGroup) in uiInfo) { 75 if (appPermGroup.shouldShow && !appPermGroup.isSystem && 76 appPermGroup.permGrantState != AppPermGroupUiInfo.PermGrantState.PERMS_DENIED && 77 appPermGroup.permGrantState != AppPermGroupUiInfo.PermGrantState.PERMS_ASK) { 78 granted++ 79 } 80 } 81 return granted 82 } 83 84 override fun onUpdate() { 85 /** 86 * Only update when either- 87 * We have a list of groups, and none have loaded their data, or 88 * All packages have loaded their data 89 */ 90 val haveAllLiveDatas = groupNames.all { permGroupPackagesLiveDatas.contains(it) } 91 val allInitialized = permGroupPackagesLiveDatas.all { it.value.isInitialized } 92 for (groupName in groupNames) { 93 allPackageData[groupName] = if (haveAllLiveDatas && allInitialized) { 94 permGroupPackagesLiveDatas[groupName]?.value?.let { uiInfo -> 95 PermGroupPackagesUiInfo(groupName, 96 getNonSystemTotal(uiInfo), getNonSystemGranted(uiInfo)) 97 } 98 } else { 99 null 100 } 101 } 102 value = allPackageData.toMap() 103 } 104 } 105