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 import android.util.Log; 24 25 import com.android.internal.annotations.GuardedBy; 26 import com.android.internal.util.XmlUtils; 27 import com.android.modules.utils.TypedXmlPullParser; 28 import com.android.modules.utils.TypedXmlSerializer; 29 import com.android.server.pm.DumpState; 30 import com.android.server.pm.PackageManagerService; 31 import com.android.server.pm.PackageManagerTracedLock; 32 33 import org.xmlpull.v1.XmlPullParser; 34 import org.xmlpull.v1.XmlPullParserException; 35 36 import java.io.IOException; 37 import java.io.PrintWriter; 38 import java.util.ArrayList; 39 import java.util.List; 40 import java.util.Map; 41 import java.util.Set; 42 43 /** 44 * Legacy permission settings for migration. 45 */ 46 public class LegacyPermissionSettings { 47 /** 48 * All of the permissions known to the system. The mapping is from permission 49 * name to permission object. 50 */ 51 @GuardedBy("mLock") 52 private final ArrayMap<String, LegacyPermission> mPermissions = new ArrayMap<>(); 53 54 /** 55 * All permission trees known to the system. The mapping is from permission tree 56 * name to permission object. 57 */ 58 @GuardedBy("mLock") 59 private final ArrayMap<String, LegacyPermission> mPermissionTrees = new ArrayMap<>(); 60 61 @NonNull 62 private final PackageManagerTracedLock mLock = new PackageManagerTracedLock(); 63 64 @NonNull getPermissions()65 public List<LegacyPermission> getPermissions() { 66 synchronized (mLock) { 67 return new ArrayList<>(mPermissions.values()); 68 } 69 } 70 71 @NonNull getPermissionTrees()72 public List<LegacyPermission> getPermissionTrees() { 73 synchronized (mLock) { 74 return new ArrayList<>(mPermissionTrees.values()); 75 } 76 } 77 replacePermissions(@onNull List<LegacyPermission> permissions)78 public void replacePermissions(@NonNull List<LegacyPermission> permissions) { 79 synchronized (mLock) { 80 mPermissions.clear(); 81 final int permissionsSize = permissions.size(); 82 for (int i = 0; i < permissionsSize; i++) { 83 final LegacyPermission permission = permissions.get(i); 84 mPermissions.put(permission.getPermissionInfo().name, permission); 85 } 86 } 87 } 88 replacePermissionTrees(@onNull List<LegacyPermission> permissionTrees)89 public void replacePermissionTrees(@NonNull List<LegacyPermission> permissionTrees) { 90 synchronized (mLock) { 91 mPermissionTrees.clear(); 92 final int permissionsSize = permissionTrees.size(); 93 for (int i = 0; i < permissionsSize; i++) { 94 final LegacyPermission permissionTree = permissionTrees.get(i); 95 mPermissionTrees.put(permissionTree.getPermissionInfo().name, permissionTree); 96 } 97 } 98 } 99 readPermissions(@onNull TypedXmlPullParser parser)100 public void readPermissions(@NonNull TypedXmlPullParser parser) throws IOException, 101 XmlPullParserException { 102 synchronized (mLock) { 103 readPermissions(mPermissions, parser); 104 } 105 } 106 readPermissionTrees(@onNull TypedXmlPullParser parser)107 public void readPermissionTrees(@NonNull TypedXmlPullParser parser) throws IOException, 108 XmlPullParserException { 109 synchronized (mLock) { 110 readPermissions(mPermissionTrees, parser); 111 } 112 } 113 readPermissions(@onNull ArrayMap<String, LegacyPermission> out, @NonNull TypedXmlPullParser parser)114 public static void readPermissions(@NonNull ArrayMap<String, LegacyPermission> out, 115 @NonNull TypedXmlPullParser parser) throws IOException, XmlPullParserException { 116 int outerDepth = parser.getDepth(); 117 int type; 118 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 119 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 120 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 121 continue; 122 } 123 124 if (!LegacyPermission.read(out, parser)) { 125 PackageManagerService.reportSettingsProblem(Log.WARN, 126 "Unknown element reading permissions: " + parser.getName() + " at " 127 + parser.getPositionDescription()); 128 } 129 XmlUtils.skipCurrentTag(parser); 130 } 131 } 132 writePermissions(@onNull TypedXmlSerializer serializer)133 public void writePermissions(@NonNull TypedXmlSerializer serializer) throws IOException { 134 synchronized (mLock) { 135 for (LegacyPermission bp : mPermissions.values()) { 136 bp.write(serializer); 137 } 138 } 139 } 140 writePermissionTrees(@onNull TypedXmlSerializer serializer)141 public void writePermissionTrees(@NonNull TypedXmlSerializer serializer) throws IOException { 142 synchronized (mLock) { 143 for (LegacyPermission bp : mPermissionTrees.values()) { 144 bp.write(serializer); 145 } 146 } 147 } 148 dumpPermissions(@onNull PrintWriter pw, @Nullable String packageName, @Nullable ArraySet<String> permissionNames, @NonNull List<LegacyPermission> permissions, @NonNull Map<String, Set<String>> appOpPermissionPackages, boolean externalStorageEnforced, @NonNull DumpState dumpState)149 public static void dumpPermissions(@NonNull PrintWriter pw, @Nullable String packageName, 150 @Nullable ArraySet<String> permissionNames, @NonNull List<LegacyPermission> permissions, 151 @NonNull Map<String, Set<String>> appOpPermissionPackages, 152 boolean externalStorageEnforced, @NonNull DumpState dumpState) { 153 boolean printedSomething = false; 154 final int permissionsSize = permissions.size(); 155 for (int i = 0; i < permissionsSize; i++) { 156 final LegacyPermission permission = permissions.get(i); 157 printedSomething = permission.dump(pw, packageName, permissionNames, 158 externalStorageEnforced, printedSomething, dumpState); 159 } 160 if (packageName == null && permissionNames == null) { 161 boolean firstEntry = true; 162 for (final Map.Entry<String, Set<String>> entry : appOpPermissionPackages.entrySet()) { 163 if (firstEntry) { 164 firstEntry = false; 165 if (dumpState.onTitlePrinted()) { 166 pw.println(); 167 } 168 pw.println("AppOp Permissions:"); 169 } 170 pw.print(" AppOp Permission "); 171 pw.print(entry.getKey()); 172 pw.println(":"); 173 for (final String appOpPackageName : entry.getValue()) { 174 pw.print(" "); 175 pw.println(appOpPackageName); 176 } 177 } 178 } 179 } 180 } 181