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 32 import org.xmlpull.v1.XmlPullParser; 33 import org.xmlpull.v1.XmlPullParserException; 34 import org.xmlpull.v1.XmlSerializer; 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 Object mLock; 63 LegacyPermissionSettings(@onNull Object lock)64 public LegacyPermissionSettings(@NonNull Object lock) { 65 mLock = lock; 66 } 67 68 @NonNull getPermissions()69 public List<LegacyPermission> getPermissions() { 70 synchronized (mLock) { 71 return new ArrayList<>(mPermissions.values()); 72 } 73 } 74 75 @NonNull getPermissionTrees()76 public List<LegacyPermission> getPermissionTrees() { 77 synchronized (mLock) { 78 return new ArrayList<>(mPermissionTrees.values()); 79 } 80 } 81 replacePermissions(@onNull List<LegacyPermission> permissions)82 public void replacePermissions(@NonNull List<LegacyPermission> permissions) { 83 synchronized (mLock) { 84 mPermissions.clear(); 85 final int permissionsSize = permissions.size(); 86 for (int i = 0; i < permissionsSize; i++) { 87 final LegacyPermission permission = permissions.get(i); 88 mPermissions.put(permission.getPermissionInfo().name, permission); 89 } 90 } 91 } 92 replacePermissionTrees(@onNull List<LegacyPermission> permissionTrees)93 public void replacePermissionTrees(@NonNull List<LegacyPermission> permissionTrees) { 94 synchronized (mLock) { 95 mPermissionTrees.clear(); 96 final int permissionsSize = permissionTrees.size(); 97 for (int i = 0; i < permissionsSize; i++) { 98 final LegacyPermission permissionTree = permissionTrees.get(i); 99 mPermissionTrees.put(permissionTree.getPermissionInfo().name, permissionTree); 100 } 101 } 102 } 103 readPermissions(@onNull TypedXmlPullParser parser)104 public void readPermissions(@NonNull TypedXmlPullParser parser) throws IOException, 105 XmlPullParserException { 106 synchronized (mLock) { 107 readPermissions(mPermissions, parser); 108 } 109 } 110 readPermissionTrees(@onNull TypedXmlPullParser parser)111 public void readPermissionTrees(@NonNull TypedXmlPullParser parser) throws IOException, 112 XmlPullParserException { 113 synchronized (mLock) { 114 readPermissions(mPermissionTrees, parser); 115 } 116 } 117 readPermissions(@onNull ArrayMap<String, LegacyPermission> out, @NonNull TypedXmlPullParser parser)118 public static void readPermissions(@NonNull ArrayMap<String, LegacyPermission> out, 119 @NonNull TypedXmlPullParser parser) throws IOException, XmlPullParserException { 120 int outerDepth = parser.getDepth(); 121 int type; 122 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 123 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 124 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 125 continue; 126 } 127 128 if (!LegacyPermission.read(out, parser)) { 129 PackageManagerService.reportSettingsProblem(Log.WARN, 130 "Unknown element reading permissions: " + parser.getName() + " at " 131 + parser.getPositionDescription()); 132 } 133 XmlUtils.skipCurrentTag(parser); 134 } 135 } 136 writePermissions(@onNull TypedXmlSerializer serializer)137 public void writePermissions(@NonNull TypedXmlSerializer serializer) throws IOException { 138 synchronized (mLock) { 139 for (LegacyPermission bp : mPermissions.values()) { 140 bp.write(serializer); 141 } 142 } 143 } 144 writePermissionTrees(@onNull TypedXmlSerializer serializer)145 public void writePermissionTrees(@NonNull TypedXmlSerializer serializer) throws IOException { 146 synchronized (mLock) { 147 for (LegacyPermission bp : mPermissionTrees.values()) { 148 bp.write(serializer); 149 } 150 } 151 } 152 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)153 public static void dumpPermissions(@NonNull PrintWriter pw, @Nullable String packageName, 154 @Nullable ArraySet<String> permissionNames, @NonNull List<LegacyPermission> permissions, 155 @NonNull Map<String, Set<String>> appOpPermissionPackages, 156 boolean externalStorageEnforced, @NonNull DumpState dumpState) { 157 boolean printedSomething = false; 158 final int permissionsSize = permissions.size(); 159 for (int i = 0; i < permissionsSize; i++) { 160 final LegacyPermission permission = permissions.get(i); 161 printedSomething = permission.dump(pw, packageName, permissionNames, 162 externalStorageEnforced, printedSomething, dumpState); 163 } 164 if (packageName == null && permissionNames == null) { 165 boolean firstEntry = true; 166 for (final Map.Entry<String, Set<String>> entry : appOpPermissionPackages.entrySet()) { 167 if (firstEntry) { 168 firstEntry = false; 169 if (dumpState.onTitlePrinted()) { 170 pw.println(); 171 } 172 pw.println("AppOp Permissions:"); 173 } 174 pw.print(" AppOp Permission "); 175 pw.print(entry.getKey()); 176 pw.println(":"); 177 for (final String appOpPackageName : entry.getValue()) { 178 pw.print(" "); 179 pw.println(appOpPackageName); 180 } 181 } 182 } 183 } 184 } 185