1 /* 2 * Copyright (C) 2017 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.server.pm.permission; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.util.ArrayMap; 22 import android.util.ArraySet; 23 24 import com.android.internal.pm.pkg.component.ParsedPermissionGroup; 25 26 import java.util.Collection; 27 28 /** 29 * Permission registry for permissions, permission trees, permission groups and related things. 30 */ 31 public class PermissionRegistry { 32 /** 33 * All of the permissions known to the system. The mapping is from permission 34 * name to permission object. 35 */ 36 private final ArrayMap<String, Permission> mPermissions = new ArrayMap<>(); 37 38 /** 39 * All permission trees known to the system. The mapping is from permission tree 40 * name to permission object. 41 */ 42 private final ArrayMap<String, Permission> mPermissionTrees = new ArrayMap<>(); 43 44 /** 45 * All permisson groups know to the system. The mapping is from permission group 46 * name to permission group object. 47 */ 48 private final ArrayMap<String, ParsedPermissionGroup> mPermissionGroups = new ArrayMap<>(); 49 50 /** 51 * Set of packages that request a particular app op. The mapping is from permission 52 * name to package names. 53 */ 54 private final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 55 56 @NonNull getPermissions()57 public Collection<Permission> getPermissions() { 58 return mPermissions.values(); 59 } 60 61 @Nullable getPermission(@onNull String permissionName)62 public Permission getPermission(@NonNull String permissionName) { 63 return mPermissions.get(permissionName); 64 } 65 addPermission(@onNull Permission permission)66 public void addPermission(@NonNull Permission permission) { 67 mPermissions.put(permission.getName(), permission); 68 } 69 removePermission(@onNull String permissionName)70 public void removePermission(@NonNull String permissionName) { 71 mPermissions.remove(permissionName); 72 } 73 74 @NonNull getPermissionTrees()75 public Collection<Permission> getPermissionTrees() { 76 return mPermissionTrees.values(); 77 } 78 79 @Nullable getPermissionTree(@onNull String permissionTreeName)80 public Permission getPermissionTree(@NonNull String permissionTreeName) { 81 return mPermissionTrees.get(permissionTreeName); 82 } 83 addPermissionTree(@onNull Permission permissionTree)84 public void addPermissionTree(@NonNull Permission permissionTree) { 85 mPermissionTrees.put(permissionTree.getName(), permissionTree); 86 } 87 88 /** 89 * Transfers ownership of permissions from one package to another. 90 */ transferPermissions(@onNull String oldPackageName, @NonNull String newPackageName)91 public void transferPermissions(@NonNull String oldPackageName, 92 @NonNull String newPackageName) { 93 for (int i = 0; i < 2; i++) { 94 ArrayMap<String, Permission> permissions = i == 0 ? mPermissionTrees : mPermissions; 95 for (final Permission permission : permissions.values()) { 96 permission.transfer(oldPackageName, newPackageName); 97 } 98 } 99 } 100 101 @NonNull getPermissionGroups()102 public Collection<ParsedPermissionGroup> getPermissionGroups() { 103 return mPermissionGroups.values(); 104 } 105 106 @Nullable getPermissionGroup(@onNull String permissionGroupName)107 public ParsedPermissionGroup getPermissionGroup(@NonNull String permissionGroupName) { 108 return mPermissionGroups.get(permissionGroupName); 109 } 110 addPermissionGroup(@onNull ParsedPermissionGroup permissionGroup)111 public void addPermissionGroup(@NonNull ParsedPermissionGroup permissionGroup) { 112 mPermissionGroups.put(permissionGroup.getName(), permissionGroup); 113 } 114 115 @NonNull getAllAppOpPermissionPackages()116 public ArrayMap<String, ArraySet<String>> getAllAppOpPermissionPackages() { 117 return mAppOpPermissionPackages; 118 } 119 120 @Nullable getAppOpPermissionPackages(@onNull String permissionName)121 public ArraySet<String> getAppOpPermissionPackages(@NonNull String permissionName) { 122 return mAppOpPermissionPackages.get(permissionName); 123 } 124 addAppOpPermissionPackage(@onNull String permissionName, @NonNull String packageName)125 public void addAppOpPermissionPackage(@NonNull String permissionName, 126 @NonNull String packageName) { 127 ArraySet<String> packageNames = mAppOpPermissionPackages.get(permissionName); 128 if (packageNames == null) { 129 packageNames = new ArraySet<>(); 130 mAppOpPermissionPackages.put(permissionName, packageNames); 131 } 132 packageNames.add(packageName); 133 } 134 removeAppOpPermissionPackage(@onNull String permissionName, @NonNull String packageName)135 public void removeAppOpPermissionPackage(@NonNull String permissionName, 136 @NonNull String packageName) { 137 final ArraySet<String> packageNames = mAppOpPermissionPackages.get(permissionName); 138 if (packageNames == null) { 139 return; 140 } 141 final boolean removed = packageNames.remove(packageName); 142 if (removed && packageNames.isEmpty()) { 143 mAppOpPermissionPackages.remove(permissionName); 144 } 145 } 146 147 /** 148 * Returns the permission tree for the given permission. 149 * @throws SecurityException If the calling UID is not allowed to add permissions to the 150 * found permission tree. 151 */ 152 @NonNull enforcePermissionTree(@onNull String permissionName, int callingUid)153 public Permission enforcePermissionTree(@NonNull String permissionName, int callingUid) { 154 return Permission.enforcePermissionTree(mPermissionTrees.values(), permissionName, 155 callingUid); 156 } 157 } 158