1 /* 2 * 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.permissioncontroller.permission.service 18 19 import android.permission.PermissionManager 20 import com.android.permissioncontroller.permission.utils.PermissionMapping 21 22 /** 23 * Takes a list of split permissions, and provides methods that return which split-permissions will 24 * be active given an app's targetSdk. 25 */ 26 class SplitPermissionIndex() { 27 private lateinit var permToGroupSplits: Set<SplitPermissionIndexEntry> 28 private lateinit var groupToGroupSplits: Set<SplitPermissionIndexEntry> 29 30 constructor(groupToGroupSplits: Set<SplitPermissionIndexEntry>) : this() { 31 this.groupToGroupSplits = groupToGroupSplits 32 } 33 34 constructor(splitPermissionInfos: List<PermissionManager.SplitPermissionInfo>) : this() { 35 val permToGroupSplits: MutableSet<SplitPermissionIndexEntry> = mutableSetOf() 36 val groupToGroupSplits: MutableSet<SplitPermissionIndexEntry> = mutableSetOf() 37 for (splitPermissionInfo in splitPermissionInfos) { 38 val splitPermission = splitPermissionInfo.splitPermission 39 for (newPerm in splitPermissionInfo.newPermissions) { 40 val splitPermissionGroup = 41 PermissionMapping.getGroupOfPlatformPermission(splitPermission) 42 val newPermGroup = PermissionMapping.getGroupOfPlatformPermission(newPerm) 43 if (newPermGroup != null) { 44 permToGroupSplits.add( 45 SplitPermissionIndexEntry( 46 splitPermission, 47 splitPermissionInfo.targetSdk, 48 newPermGroup 49 ) 50 ) 51 } 52 if (splitPermissionGroup != null && newPermGroup != null) { 53 groupToGroupSplits.add( 54 SplitPermissionIndexEntry( 55 splitPermissionGroup, 56 splitPermissionInfo.targetSdk, 57 newPermGroup 58 ) 59 ) 60 } 61 } 62 } 63 this.permToGroupSplits = permToGroupSplits 64 this.groupToGroupSplits = groupToGroupSplits 65 } 66 67 /** 68 * Given a split permission, and a package targetSdkVersion, return permission groups of new 69 * permissions. See <split-permission> tag. 70 * 71 * @param splitPermission the split permission (i.e. old permission) 72 * @param appTargetSdk app target sdk 73 * @return the permission groups calculated from new permissions 74 */ getPermissionGroupsFromSplitPermissionnull75 fun getPermissionGroupsFromSplitPermission( 76 splitPermission: String, 77 appTargetSdk: Int 78 ): List<String> { 79 return permToGroupSplits 80 .filter { it.splitPermissionOrGroup == splitPermission && appTargetSdk < it.targetSdk } 81 .map { it.newPermissionGroup } 82 .toList() 83 } 84 85 /** 86 * Given a split permission, and a package targetSdkVersion, return permission groups of new 87 * permissions. See <split-permission> tag. 88 * 89 * @param splitPermissionGroup permission group of a split permission 90 * @param appTargetSdk app target sdk 91 * @return the permission groups calculated from new permissions 92 */ getPermissionGroupsFromSplitPermissionGroupnull93 fun getPermissionGroupsFromSplitPermissionGroup( 94 splitPermissionGroup: String, 95 appTargetSdk: Int 96 ): List<String> { 97 return groupToGroupSplits 98 .filter { 99 it.splitPermissionOrGroup == splitPermissionGroup && appTargetSdk < it.targetSdk 100 } 101 .map { it.newPermissionGroup } 102 .toList() 103 } 104 105 /** 106 * Given a permission group, and package's target sdk find permission groups of the split 107 * permissions, see <split-permission> tag. 108 * 109 * @param permissionGroup permission group mapped to new permissions in <split-permission> tag 110 * @param appTargetSdk app target sdk 111 * @return the permission group for the split permissions 112 */ getSplitPermissionGroupsnull113 fun getSplitPermissionGroups(permissionGroup: String, appTargetSdk: Int): List<String> { 114 return groupToGroupSplits 115 .filter { it.newPermissionGroup == permissionGroup && appTargetSdk < it.targetSdk } 116 .map { it.splitPermissionOrGroup } 117 .toList() 118 } 119 120 data class SplitPermissionIndexEntry( 121 val splitPermissionOrGroup: String, 122 /** The split only applies to app target sdk below this */ 123 val targetSdk: Int, 124 val newPermissionGroup: String 125 ) 126 } 127