From 96f0ef490efd3ca055a2a4f29dfcaaf727e6ec41 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 14 Oct 2020 19:37:31 -0700 Subject: [PATCH] Second refactoring for BasePermission. - Made all fields private. - Replaced ParsedPermission usage with PermissionInfo. The BasePermission class was using ParsedPermission and PermissionInfo to keep track of the same set of information. Since we only need to support getPermissionInfo(), we can keep track of the information with PermissionInfo alone, dropping dependency on ParsedPermission which isn't and won't be an API. The logic of addToTree() and updateDynamicPermission() became a bit weird/broken after the package parser refactoring regarding how the new ParsedPermission/PermissionInfo was derived, so Pie BasePermission implementation was taken as a reference for what the intended behavior actually was. Bug: 158736025 Test: presubmit Change-Id: I414d43c3e98e9267d74de35eb62b7d1b6524a13f --- .../parsing/component/ParsedPermission.java | 16 - .../server/pm/PackageManagerService.java | 2 +- .../server/pm/permission/BasePermission.java | 419 +++++++++--------- .../permission/PermissionManagerService.java | 70 +-- .../pm/permission/UidPermissionState.java | 2 +- 5 files changed, 254 insertions(+), 255 deletions(-) diff --git a/core/java/android/content/pm/parsing/component/ParsedPermission.java b/core/java/android/content/pm/parsing/component/ParsedPermission.java index ced322649c66d..f99a0b1dcadb8 100644 --- a/core/java/android/content/pm/parsing/component/ParsedPermission.java +++ b/core/java/android/content/pm/parsing/component/ParsedPermission.java @@ -54,22 +54,6 @@ public class ParsedPermission extends ParsedComponent { this.parsedPermissionGroup = other.parsedPermissionGroup; } - public ParsedPermission(ParsedPermission other, PermissionInfo pendingPermissionInfo, - String packageName, String name) { - this(other); - - this.flags = pendingPermissionInfo.flags; - this.descriptionRes = pendingPermissionInfo.descriptionRes; - - this.backgroundPermission = pendingPermissionInfo.backgroundPermission; - this.group = pendingPermissionInfo.group; - this.requestRes = pendingPermissionInfo.requestRes; - this.protectionLevel = pendingPermissionInfo.protectionLevel; - - setName(name); - setPackageName(packageName); - } - public ParsedPermission setGroup(String group) { this.group = TextUtils.safeIntern(group); return this; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 9caa91b63deee..bb95f6434c814 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17756,7 +17756,7 @@ public class PackageManagerService extends IPackageManager.Stub // also includes the "updating the same package" case, of course. // "updating same package" could also involve key-rotation. final boolean sigsOk; - final String sourcePackageName = bp.getSourcePackageName(); + final String sourcePackageName = bp.getPackageName(); final PackageSetting sourcePackageSetting; synchronized (mLock) { sourcePackageSetting = mSettings.getPackageLPr(sourcePackageName); diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index fedbed2f7a01a..bebb67686696e 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -29,6 +29,7 @@ import static com.android.server.pm.Settings.TAG_ITEM; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.PermissionInfo; import android.content.pm.parsing.component.ParsedPermission; @@ -39,8 +40,6 @@ import android.util.Slog; import com.android.server.pm.DumpState; import com.android.server.pm.PackageManagerService; -import com.android.server.pm.PackageSettingBase; -import com.android.server.pm.parsing.PackageInfoUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; import libcore.util.EmptyArray; @@ -81,269 +80,282 @@ public final class BasePermission { @Retention(RetentionPolicy.SOURCE) public @interface ProtectionLevel {} - final String name; + @NonNull + private final String mName; - final @PermissionType int type; + private final @PermissionType int mType; - String sourcePackageName; + private String mPackageName; - int protectionLevel; + private int mProtectionLevel; - ParsedPermission perm; + @Nullable + private PermissionInfo mPermissionInfo; - PermissionInfo pendingPermissionInfo; + @Nullable + private PermissionInfo mPendingPermissionInfo; /** UID that owns the definition of this permission */ - int uid; + private int mUid; /** Additional GIDs given to apps granted this permission */ @NonNull - private int[] gids = EmptyArray.INT; + private int[] mGids = EmptyArray.INT; /** - * Flag indicating that {@link #gids} should be adjusted based on the + * Flag indicating that {@link #mGids} should be adjusted based on the * {@link UserHandle} the granted app is running as. */ - private boolean perUser; + private boolean mGidsPerUser; - public BasePermission(String _name, String _sourcePackageName, @PermissionType int _type) { - name = _name; - sourcePackageName = _sourcePackageName; - type = _type; + public BasePermission(@NonNull String name, String packageName, @PermissionType int type) { + mName = name; + mPackageName = packageName; + mType = type; // Default to most conservative protection level. - protectionLevel = PermissionInfo.PROTECTION_SIGNATURE; + mProtectionLevel = PermissionInfo.PROTECTION_SIGNATURE; } @Override public String toString() { - return "BasePermission{" + Integer.toHexString(System.identityHashCode(this)) + " " + name + return "BasePermission{" + Integer.toHexString(System.identityHashCode(this)) + " " + mName + "}"; } + @NonNull public String getName() { - return name; + return mName; } + public int getProtectionLevel() { - return protectionLevel; + return mProtectionLevel; } - public String getSourcePackageName() { - return sourcePackageName; + + public String getPackageName() { + return mPackageName; } + public int getType() { - return type; + return mType; } + public int getUid() { - return uid; + return mUid; } - public void setGids(@NonNull int[] gids, boolean perUser) { - this.gids = gids; - this.perUser = perUser; + + public void setGids(@NonNull int[] gids, boolean gidsPerUser) { + mGids = gids; + mGidsPerUser = gidsPerUser; } - public void setPermission(@Nullable ParsedPermission perm) { - this.perm = perm; + + public void setPermissionInfo(@Nullable PermissionInfo permissionInfo) { + mPermissionInfo = permissionInfo; } public boolean hasGids() { - return gids.length != 0; + return mGids.length != 0; } @NonNull public int[] computeGids(int userId) { - if (perUser) { - final int[] userGids = new int[gids.length]; - for (int i = 0; i < gids.length; i++) { - final int gid = gids[i]; + if (mGidsPerUser) { + final int[] userGids = new int[mGids.length]; + for (int i = 0; i < mGids.length; i++) { + final int gid = mGids[i]; userGids[i] = UserHandle.getUid(userId, gid); } return userGids; } else { - return gids.length != 0 ? gids.clone() : gids; + return mGids.length != 0 ? mGids.clone() : mGids; } } public int calculateFootprint(BasePermission perm) { - if (uid == perm.uid) { - return perm.name.length() + perm.perm.calculateFootprint(); + if (mUid == perm.mUid) { + return perm.mName.length() + perm.mPermissionInfo.calculateFootprint(); } return 0; } public boolean isPermission(ParsedPermission perm) { - if (this.perm == null) { + if (mPermissionInfo == null) { return false; } - return Objects.equals(this.perm.getPackageName(), perm.getPackageName()) - && Objects.equals(this.perm.getName(), perm.getName()); + return Objects.equals(mPermissionInfo.packageName, perm.getPackageName()) + && Objects.equals(mPermissionInfo.name, perm.getName()); } public boolean isDynamic() { - return type == TYPE_DYNAMIC; + return mType == TYPE_DYNAMIC; } - public boolean isNormal() { - return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) + return (mProtectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_NORMAL; } public boolean isRuntime() { - return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) + return (mProtectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_DANGEROUS; } public boolean isRemoved() { - return perm != null && (perm.getFlags() & PermissionInfo.FLAG_REMOVED) != 0; + return mPermissionInfo != null + && (mPermissionInfo.flags & PermissionInfo.FLAG_REMOVED) != 0; } public boolean isSoftRestricted() { - return perm != null && (perm.getFlags() & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0; + return mPermissionInfo != null + && (mPermissionInfo.flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0; } public boolean isHardRestricted() { - return perm != null && (perm.getFlags() & PermissionInfo.FLAG_HARD_RESTRICTED) != 0; + return mPermissionInfo != null + && (mPermissionInfo.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0; } public boolean isHardOrSoftRestricted() { - return perm != null && (perm.getFlags() & (PermissionInfo.FLAG_HARD_RESTRICTED - | PermissionInfo.FLAG_SOFT_RESTRICTED)) != 0; + return mPermissionInfo != null && (mPermissionInfo.flags + & (PermissionInfo.FLAG_HARD_RESTRICTED | PermissionInfo.FLAG_SOFT_RESTRICTED)) != 0; } public boolean isImmutablyRestricted() { - return perm != null && (perm.getFlags() & PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) != 0; + return mPermissionInfo != null + && (mPermissionInfo.flags & PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) != 0; } public boolean isInstallerExemptIgnored() { - return perm != null - && (perm.getFlags() & PermissionInfo.FLAG_INSTALLER_EXEMPT_IGNORED) != 0; + return mPermissionInfo != null + && (mPermissionInfo.flags & PermissionInfo.FLAG_INSTALLER_EXEMPT_IGNORED) != 0; } public boolean isSignature() { - return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == - PermissionInfo.PROTECTION_SIGNATURE; + return (mProtectionLevel & PermissionInfo.PROTECTION_MASK_BASE) + == PermissionInfo.PROTECTION_SIGNATURE; } public boolean isAppOp() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; } public boolean isDevelopment() { return isSignature() - && (protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0; + && (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0; } public boolean isInstaller() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0; } public boolean isInstant() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0; } public boolean isOEM() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_OEM) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_OEM) != 0; } public boolean isPre23() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_PRE23) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_PRE23) != 0; } public boolean isPreInstalled() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0; } public boolean isPrivileged() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0; } public boolean isRuntimeOnly() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0; } public boolean isSetup() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0; } public boolean isVerifier() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0; } public boolean isVendorPrivileged() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0; } public boolean isSystemTextClassifier() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER) + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER) != 0; } public boolean isWellbeing() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_WELLBEING) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_WELLBEING) != 0; } public boolean isDocumenter() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_DOCUMENTER) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_DOCUMENTER) != 0; } public boolean isConfigurator() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_CONFIGURATOR) + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_CONFIGURATOR) != 0; } public boolean isIncidentReportApprover() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER) != 0; } public boolean isAppPredictor() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0; } public boolean isCompanion() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0; } public boolean isRetailDemo() { - return (protectionLevel & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0; + return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0; } public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) { - if (!origPackageName.equals(sourcePackageName)) { + if (!origPackageName.equals(mPackageName)) { return; } - sourcePackageName = newPackageName; - perm = null; - if (pendingPermissionInfo != null) { - pendingPermissionInfo.packageName = newPackageName; + mPackageName = newPackageName; + mPermissionInfo = null; + if (mPendingPermissionInfo != null) { + mPendingPermissionInfo.packageName = newPackageName; } - uid = 0; - gids = EmptyArray.INT; - perUser = false; + mUid = 0; + mGids = EmptyArray.INT; + mGidsPerUser = false; } public boolean addToTree(@ProtectionLevel int protectionLevel, - @NonNull PermissionInfo info, @NonNull BasePermission tree) { + @NonNull PermissionInfo permissionInfo, @NonNull BasePermission tree) { final boolean changed = - (this.protectionLevel != protectionLevel - || perm == null - || uid != tree.uid - || !Objects.equals(perm.getPackageName(), tree.perm.getPackageName()) - || !comparePermissionInfos(perm, info)); - this.protectionLevel = protectionLevel; - info = new PermissionInfo(info); - info.protectionLevel = protectionLevel; - perm = new ParsedPermission(tree.perm); - uid = tree.uid; + (mProtectionLevel != protectionLevel + || mPermissionInfo == null + || mUid != tree.mUid + || !Objects.equals(mPermissionInfo.packageName, + tree.mPermissionInfo.packageName) + || !comparePermissionInfos(mPermissionInfo, permissionInfo)); + mProtectionLevel = protectionLevel; + mPermissionInfo = new PermissionInfo(permissionInfo); + mPermissionInfo.protectionLevel = protectionLevel; + mPermissionInfo.packageName = tree.mPermissionInfo.packageName; + mUid = tree.mUid; return changed; } public void updateDynamicPermission(Collection permissionTrees) { if (PackageManagerService.DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" - + getName() + " pkg=" + getSourcePackageName() - + " info=" + pendingPermissionInfo); - if (pendingPermissionInfo != null) { - final BasePermission tree = findPermissionTree(permissionTrees, name); - if (tree != null && tree.perm != null) { - perm = new ParsedPermission(tree.perm, pendingPermissionInfo, - tree.perm.getPackageName(), name); - uid = tree.uid; + + getName() + " pkg=" + getPackageName() + + " info=" + mPendingPermissionInfo); + if (mPendingPermissionInfo != null) { + final BasePermission tree = findPermissionTree(permissionTrees, mName); + if (tree != null && tree.mPermissionInfo != null) { + mPermissionInfo = new PermissionInfo(mPendingPermissionInfo); + mPermissionInfo.packageName = tree.mPermissionInfo.packageName; + mPermissionInfo.name = mName; + mUid = tree.mUid; } } } static BasePermission createOrUpdate(PackageManagerInternal packageManagerInternal, - @Nullable BasePermission bp, @NonNull ParsedPermission p, + @Nullable BasePermission bp, @NonNull PermissionInfo p, @NonNull AndroidPackage pkg, Collection permissionTrees, boolean chatty) { - final PackageSettingBase pkgSetting = - (PackageSettingBase) packageManagerInternal.getPackageSetting(pkg.getPackageName()); // Allow system apps to redefine non-system permissions - if (bp != null && !Objects.equals(bp.sourcePackageName, p.getPackageName())) { + if (bp != null && !Objects.equals(bp.mPackageName, p.packageName)) { final boolean currentOwnerIsSystem; - if (bp.perm == null) { + if (bp.mPermissionInfo == null) { currentOwnerIsSystem = false; } else { AndroidPackage currentPackage = packageManagerInternal.getPackage( - bp.perm.getPackageName()); + bp.mPermissionInfo.packageName); if (currentPackage == null) { currentOwnerIsSystem = false; } else { @@ -352,52 +364,52 @@ public final class BasePermission { } if (pkg.isSystem()) { - if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { + if (bp.mType == BasePermission.TYPE_BUILTIN && bp.mPermissionInfo == null) { // It's a built-in permission and no owner, take ownership now - p.setFlags(p.getFlags() | PermissionInfo.FLAG_INSTALLED); - bp.perm = p; - bp.uid = pkg.getUid(); - bp.sourcePackageName = p.getPackageName(); + p.flags |= PermissionInfo.FLAG_INSTALLED; + bp.mPermissionInfo = p; + bp.mUid = pkg.getUid(); + bp.mPackageName = p.packageName; } else if (!currentOwnerIsSystem) { String msg = "New decl " + pkg + " of permission " - + p.getName() + " is system; overriding " + bp.sourcePackageName; + + p.name + " is system; overriding " + bp.mPackageName; PackageManagerService.reportSettingsProblem(Log.WARN, msg); bp = null; } } } if (bp == null) { - bp = new BasePermission(p.getName(), p.getPackageName(), TYPE_NORMAL); + bp = new BasePermission(p.name, p.packageName, TYPE_NORMAL); } StringBuilder r = null; - if (bp.perm == null) { - if (bp.sourcePackageName == null - || bp.sourcePackageName.equals(p.getPackageName())) { - final BasePermission tree = findPermissionTree(permissionTrees, p.getName()); + if (bp.mPermissionInfo == null) { + if (bp.mPackageName == null + || bp.mPackageName.equals(p.packageName)) { + final BasePermission tree = findPermissionTree(permissionTrees, p.name); if (tree == null - || tree.sourcePackageName.equals(p.getPackageName())) { - p.setFlags(p.getFlags() | PermissionInfo.FLAG_INSTALLED); - bp.perm = p; - bp.uid = pkg.getUid(); - bp.sourcePackageName = p.getPackageName(); + || tree.mPackageName.equals(p.packageName)) { + p.flags |= PermissionInfo.FLAG_INSTALLED; + bp.mPermissionInfo = p; + bp.mUid = pkg.getUid(); + bp.mPackageName = p.packageName; if (chatty) { if (r == null) { r = new StringBuilder(256); } else { r.append(' '); } - r.append(p.getName()); + r.append(p.name); } } else { - Slog.w(TAG, "Permission " + p.getName() + " from package " - + p.getPackageName() + " ignored: base tree " - + tree.name + " is from package " - + tree.sourcePackageName); + Slog.w(TAG, "Permission " + p.name + " from package " + + p.packageName + " ignored: base tree " + + tree.mName + " is from package " + + tree.mPackageName); } } else { - Slog.w(TAG, "Permission " + p.getName() + " from package " - + p.getPackageName() + " ignored: original from " - + bp.sourcePackageName); + Slog.w(TAG, "Permission " + p.name + " from package " + + p.packageName + " ignored: original from " + + bp.mPackageName); } } else if (chatty) { if (r == null) { @@ -406,11 +418,10 @@ public final class BasePermission { r.append(' '); } r.append("DUP:"); - r.append(p.getName()); + r.append(p.name); } - if (bp.perm != null && Objects.equals(bp.perm.getPackageName(), p.getPackageName()) - && Objects.equals(bp.perm.getName(), p.getName())) { - bp.protectionLevel = p.getProtectionLevel(); + if (bp.mPermissionInfo == p) { + bp.mProtectionLevel = p.protectionLevel; } if (PackageManagerService.DEBUG_PACKAGE_SCANNING && r != null) { Log.d(TAG, " Permissions: " + r); @@ -423,12 +434,12 @@ public final class BasePermission { if (permName != null) { BasePermission bp = findPermissionTree(permissionTrees, permName); if (bp != null) { - if (bp.uid == UserHandle.getAppId(callingUid)) { + if (bp.mUid == UserHandle.getAppId(callingUid)) { return bp; } throw new SecurityException("Calling uid " + callingUid + " is not allowed to add to permission tree " - + bp.name + " owned by uid " + bp.uid); + + bp.mName + " owned by uid " + bp.mUid); } } throw new SecurityException("No permission tree found for " + permName); @@ -437,18 +448,31 @@ public final class BasePermission { private static BasePermission findPermissionTree( Collection permissionTrees, String permName) { for (BasePermission bp : permissionTrees) { - if (permName.startsWith(bp.name) && - permName.length() > bp.name.length() && - permName.charAt(bp.name.length()) == '.') { + if (permName.startsWith(bp.mName) + && permName.length() > bp.mName.length() + && permName.charAt(bp.mName.length()) == '.') { return bp; } } return null; } + @Nullable + public String getBackgroundPermission() { + return mPermissionInfo != null ? mPermissionInfo.backgroundPermission : null; + } + @Nullable public String getGroup() { - return perm != null ? perm.getGroup() : null; + return mPermissionInfo != null ? mPermissionInfo.group : null; + } + + public int getProtection() { + return mProtectionLevel & PermissionInfo.PROTECTION_MASK_BASE; + } + + public int getProtectionFlags() { + return mProtectionLevel & PermissionInfo.PROTECTION_MASK_FLAGS; } @NonNull @@ -459,21 +483,24 @@ public final class BasePermission { @NonNull public PermissionInfo generatePermissionInfo(int flags, int targetSdkVersion) { PermissionInfo permissionInfo; - if (perm != null) { - permissionInfo = PackageInfoUtils.generatePermissionInfo(perm, flags); + if (mPermissionInfo != null) { + permissionInfo = new PermissionInfo(mPermissionInfo); + if ((flags & PackageManager.GET_META_DATA) != PackageManager.GET_META_DATA) { + permissionInfo.metaData = null; + } } else { permissionInfo = new PermissionInfo(); - permissionInfo.name = name; - permissionInfo.packageName = sourcePackageName; - permissionInfo.nonLocalizedLabel = name; + permissionInfo.name = mName; + permissionInfo.packageName = mPackageName; + permissionInfo.nonLocalizedLabel = mName; } if (targetSdkVersion >= Build.VERSION_CODES.O) { - permissionInfo.protectionLevel = protectionLevel; + permissionInfo.protectionLevel = mProtectionLevel; } else { - final int protection = protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; + final int protection = mProtectionLevel & PermissionInfo.PROTECTION_MASK_BASE; if (protection == PermissionInfo.PROTECTION_SIGNATURE) { // Signature permission's protection flags are always reported. - permissionInfo.protectionLevel = protectionLevel; + permissionInfo.protectionLevel = mProtectionLevel; } else { permissionInfo.protectionLevel = protection; } @@ -499,23 +526,23 @@ public final class BasePermission { final boolean dynamic = "dynamic".equals(ptype); BasePermission bp = out.get(name); // If the permission is builtin, do not clobber it. - if (bp == null || bp.type != TYPE_BUILTIN) { + if (bp == null || bp.mType != TYPE_BUILTIN) { bp = new BasePermission(name.intern(), sourcePackage, dynamic ? TYPE_DYNAMIC : TYPE_NORMAL); } - bp.protectionLevel = readInt(parser, null, "protection", + bp.mProtectionLevel = readInt(parser, null, "protection", PermissionInfo.PROTECTION_NORMAL); - bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel); + bp.mProtectionLevel = PermissionInfo.fixProtectionLevel(bp.mProtectionLevel); if (dynamic) { final PermissionInfo pi = new PermissionInfo(); pi.packageName = sourcePackage.intern(); pi.name = name.intern(); pi.icon = readInt(parser, null, "icon", 0); pi.nonLocalizedLabel = parser.getAttributeValue(null, "label"); - pi.protectionLevel = bp.protectionLevel; - bp.pendingPermissionInfo = pi; + pi.protectionLevel = bp.mProtectionLevel; + bp.mPendingPermissionInfo = pi; } - out.put(bp.name, bp); + out.put(bp.mName, bp); return true; } @@ -536,22 +563,23 @@ public final class BasePermission { } public void writeLPr(@NonNull XmlSerializer serializer) throws IOException { - if (sourcePackageName == null) { + if (mPackageName == null) { return; } serializer.startTag(null, TAG_ITEM); - serializer.attribute(null, ATTR_NAME, name); - serializer.attribute(null, ATTR_PACKAGE, sourcePackageName); - if (protectionLevel != PermissionInfo.PROTECTION_NORMAL) { - serializer.attribute(null, "protection", Integer.toString(protectionLevel)); + serializer.attribute(null, ATTR_NAME, mName); + serializer.attribute(null, ATTR_PACKAGE, mPackageName); + if (mProtectionLevel != PermissionInfo.PROTECTION_NORMAL) { + serializer.attribute(null, "protection", Integer.toString(mProtectionLevel)); } - if (type == BasePermission.TYPE_DYNAMIC) { - if (perm != null || pendingPermissionInfo != null) { + if (mType == BasePermission.TYPE_DYNAMIC) { + if (mPermissionInfo != null || mPendingPermissionInfo != null) { serializer.attribute(null, "type", "dynamic"); - int icon = perm != null ? perm.getIcon() : pendingPermissionInfo.icon; - CharSequence nonLocalizedLabel = perm != null - ? perm.getNonLocalizedLabel() - : pendingPermissionInfo.nonLocalizedLabel; + int icon = mPermissionInfo != null ? mPermissionInfo.icon + : mPendingPermissionInfo.icon; + CharSequence nonLocalizedLabel = mPermissionInfo != null + ? mPermissionInfo.nonLocalizedLabel + : mPendingPermissionInfo.nonLocalizedLabel; if (icon != 0) { serializer.attribute(null, "icon", Integer.toString(icon)); @@ -564,27 +592,14 @@ public final class BasePermission { serializer.endTag(null, TAG_ITEM); } - private static boolean compareStrings(CharSequence s1, CharSequence s2) { - if (s1 == null) { - return s2 == null; - } - if (s2 == null) { - return false; - } - if (s1.getClass() != s2.getClass()) { - return false; - } - return s1.equals(s2); - } - - private static boolean comparePermissionInfos(ParsedPermission pi1, PermissionInfo pi2) { - if (pi1.getIcon() != pi2.icon) return false; - if (pi1.getLogo() != pi2.logo) return false; - if (pi1.getProtectionLevel() != pi2.protectionLevel) return false; - if (!compareStrings(pi1.getName(), pi2.name)) return false; - if (!compareStrings(pi1.getNonLocalizedLabel(), pi2.nonLocalizedLabel)) return false; + private static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { + if (pi1.icon != pi2.icon) return false; + if (pi1.logo != pi2.logo) return false; + if (pi1.protectionLevel != pi2.protectionLevel) return false; + if (!Objects.equals(pi1.name, pi2.name)) return false; + if (!Objects.equals(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; // We'll take care of setting this one. - if (!compareStrings(pi1.getPackageName(), pi2.packageName)) return false; + if (!Objects.equals(pi1.packageName, pi2.packageName)) return false; // These are not currently stored in settings. //if (!compareStrings(pi1.group, pi2.group)) return false; //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; @@ -596,36 +611,34 @@ public final class BasePermission { public boolean dumpPermissionsLPr(@NonNull PrintWriter pw, @NonNull String packageName, @NonNull Set permissionNames, boolean readEnforced, boolean printedSomething, @NonNull DumpState dumpState) { - if (packageName != null && !packageName.equals(sourcePackageName)) { + if (packageName != null && !packageName.equals(mPackageName)) { return false; } - if (permissionNames != null && !permissionNames.contains(name)) { + if (permissionNames != null && !permissionNames.contains(mName)) { return false; } if (!printedSomething) { if (dumpState.onTitlePrinted()) pw.println(); pw.println("Permissions:"); - printedSomething = true; } - pw.print(" Permission ["); pw.print(name); pw.print("] ("); + pw.print(" Permission ["); pw.print(mName); pw.print("] ("); pw.print(Integer.toHexString(System.identityHashCode(this))); pw.println("):"); - pw.print(" sourcePackage="); pw.println(sourcePackageName); - pw.print(" uid="); pw.print(uid); - pw.print(" gids="); pw.print(Arrays.toString( - computeGids(UserHandle.USER_SYSTEM))); - pw.print(" type="); pw.print(type); - pw.print(" prot="); - pw.println(PermissionInfo.protectionToString(protectionLevel)); - if (perm != null) { - pw.print(" perm="); pw.println(perm); - if ((perm.getFlags() & PermissionInfo.FLAG_INSTALLED) == 0 - || (perm.getFlags() & PermissionInfo.FLAG_REMOVED) != 0) { - pw.print(" flags=0x"); pw.println(Integer.toHexString(perm.getFlags())); + pw.print(" sourcePackage="); pw.println(mPackageName); + pw.print(" uid="); pw.print(mUid); + pw.print(" gids="); pw.print(Arrays.toString(computeGids(UserHandle.USER_SYSTEM))); + pw.print(" type="); pw.print(mType); + pw.print(" prot="); + pw.println(PermissionInfo.protectionToString(mProtectionLevel)); + if (mPermissionInfo != null) { + pw.print(" perm="); pw.println(mPermissionInfo); + if ((mPermissionInfo.flags & PermissionInfo.FLAG_INSTALLED) == 0 + || (mPermissionInfo.flags & PermissionInfo.FLAG_REMOVED) != 0) { + pw.print(" flags=0x"); pw.println(Integer.toHexString(mPermissionInfo.flags)); } } - if (READ_EXTERNAL_STORAGE.equals(name)) { + if (READ_EXTERNAL_STORAGE.equals(mName)) { pw.print(" enforced="); pw.println(readEnforced); } diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 45872a833469a..6bc900038bc9a 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -615,7 +615,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); if (added) { enforcePermissionCapLocked(info, tree); - bp = new BasePermission(info.name, tree.getSourcePackageName(), + bp = new BasePermission(info.name, tree.getPackageName(), BasePermission.TYPE_DYNAMIC); } else if (!bp.isDynamic()) { throw new SecurityException("Not allowed to modify non-dynamic permission " @@ -2349,17 +2349,19 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } + final PermissionInfo permissionInfo = PackageInfoUtils.generatePermissionInfo(p, + PackageManager.GET_META_DATA); if (p.isTree()) { final BasePermission bp = BasePermission.createOrUpdate( mPackageManagerInt, - mSettings.getPermissionTreeLocked(p.getName()), p, pkg, + mSettings.getPermissionTreeLocked(p.getName()), permissionInfo, pkg, mSettings.getAllPermissionTreesLocked(), chatty); mSettings.putPermissionTreeLocked(p.getName(), bp); } else { final BasePermission bp = BasePermission.createOrUpdate( mPackageManagerInt, mSettings.getPermissionLocked(p.getName()), - p, pkg, mSettings.getAllPermissionTreesLocked(), chatty); + permissionInfo, pkg, mSettings.getAllPermissionTreesLocked(), chatty); mSettings.putPermissionLocked(p.getName(), bp); } } @@ -2419,7 +2421,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { bp = mSettings.mPermissionTrees.get(p.getName()); } if (bp != null && bp.isPermission(p)) { - bp.setPermission(null); + bp.setPermissionInfo(null); if (DEBUG_REMOVE && chatty) { if (r == null) { r = new StringBuilder(256); @@ -2610,7 +2612,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (permission == null) { continue; } - if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME) + if (Objects.equals(permission.getPackageName(), PLATFORM_PACKAGE_NAME) && permission.isRuntime() && !permission.isRemoved()) { if (permission.isHardOrSoftRestricted() || permission.isImmutablyRestricted()) { @@ -2803,10 +2805,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { boolean wasChanged = false; boolean restrictionExempt = - (origState.getPermissionFlags(bp.name) + (origState.getPermissionFlags(bp.getName()) & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0; boolean restrictionApplied = (origState.getPermissionFlags( - bp.name) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0; + bp.getName()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0; if (appSupportsRuntimePermissions) { // If hard restricted we don't allow holding it @@ -2854,7 +2856,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (origPermState == null) { // New permission if (PLATFORM_PACKAGE_NAME.equals( - bp.getSourcePackageName())) { + bp.getPackageName())) { if (!bp.isRemoved()) { flags |= FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT; @@ -2863,7 +2865,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - if (!uidState.isPermissionGranted(bp.name) + if (!uidState.isPermissionGranted(bp.getName()) && uidState.grantPermission(bp)) { wasChanged = true; } @@ -2900,7 +2902,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { flags); } else { if (DEBUG_PERMISSIONS) { - boolean wasGranted = uidState.isPermissionGranted(bp.name); + boolean wasGranted = uidState.isPermissionGranted(bp.getName()); if (wasGranted || bp.isAppOp()) { Slog.i(TAG, (wasGranted ? "Un-granting" : "Not granting") + " permission " + perm @@ -2912,7 +2914,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { + ")"); } } - if (uidState.removePermissionState(bp.name)) { + if (uidState.removePermissionState(bp.getName())) { changedInstallPermission = true; } } @@ -3295,7 +3297,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final boolean isPrivilegedPermission = bp.isPrivileged() || isVendorPrivilegedPermission; final boolean isOemPermission = bp.isOEM(); if (!allowed && (isPrivilegedPermission || isOemPermission) && pkg.isSystem()) { - final String permissionName = bp.name; + final String permissionName = bp.getName(); // For updated system applications, a privileged/oem permission // is granted only if it had been defined by the original application. if (pkgSetting.getPkgState().isUpdatedSystemApp()) { @@ -3443,7 +3445,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { @Nullable private PackageSetting getSourcePackageSetting(@NonNull BasePermission bp) { - final String sourcePackageName = bp.getSourcePackageName(); + final String sourcePackageName = bp.getPackageName(); return mPackageManagerInt.getPackageSetting(sourcePackageName); } @@ -3453,14 +3455,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { return false; } final boolean isPlatformPermission = PLATFORM_PACKAGE_NAME.equals( - permission.getSourcePackageName()); + permission.getPackageName()); if (!isPlatformPermission) { return true; } if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) { return true; } - final String permissionName = permission.name; + final String permissionName = permission.getName(); if (isInSystemConfigPrivAppPermissions(pkg, permissionName)) { return true; } @@ -3847,7 +3849,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // TODO(zhanghai): Why are we only killing the UID when GIDs changed, instead of any // permission change? - if (uidState.removePermissionState(bp.name) && bp.hasGids()) { + if (uidState.removePermissionState(bp.getName()) && bp.hasGids()) { affectedUserId = userId; } } @@ -3888,7 +3890,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (!usedPermissions.contains(permissionState.getName())) { BasePermission bp = mSettings.getPermissionLocked(permissionState.getName()); if (bp != null) { - if (uidState.removePermissionState(bp.name) && permissionState.isRuntime()) { + if (uidState.removePermissionState(bp.getName()) + && permissionState.isRuntime()) { runtimePermissionChanged = true; } } @@ -3959,9 +3962,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { // Only system declares background permissions, hence mapping does never change. mBackgroundPermissions = new ArrayMap<>(); for (BasePermission bp : mSettings.getAllPermissionsLocked()) { - if (bp.perm != null && bp.perm.getBackgroundPermission() != null) { - String fgPerm = bp.name; - String bgPerm = bp.perm.getBackgroundPermission(); + if (bp.getBackgroundPermission() != null) { + String fgPerm = bp.getName(); + String bgPerm = bp.getBackgroundPermission(); List fgPerms = mBackgroundPermissions.get(bgPerm); if (fgPerms == null) { @@ -4110,7 +4113,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (bp.isDynamic()) { bp.updateDynamicPermission(mSettings.mPermissionTrees.values()); } - if (!packageName.equals(bp.getSourcePackageName())) { + if (!packageName.equals(bp.getPackageName())) { // Not checking sourcePackageSetting because it can be null when // the permission source package is the target package and the target package is // being uninstalled, @@ -4131,7 +4134,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // From all other packages if (pkg == null || !hasPermission(pkg, bp.getName())) { Slog.i(TAG, "Removing permission " + bp.getName() - + " that used to be declared by " + bp.getSourcePackageName()); + + " that used to be declared by " + bp.getPackageName()); if (bp.isRuntime()) { final int[] userIds = mUserManagerInt.getUserIds(); final int numUserIds = userIds.length; @@ -4153,7 +4156,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { + p.getPackageName() + " and user " + userId); continue; } - uidState.removePermissionState(bp.name); + uidState.removePermissionState(bp.getName()); } } }); @@ -4162,16 +4165,16 @@ public class PermissionManagerService extends IPermissionManager.Stub { continue; } final AndroidPackage sourcePkg = - mPackageManagerInt.getPackage(bp.getSourcePackageName()); + mPackageManagerInt.getPackage(bp.getPackageName()); final PackageSetting sourcePs = (PackageSetting) mPackageManagerInt.getPackageSetting( - bp.getSourcePackageName()); + bp.getPackageName()); synchronized (mLock) { if (sourcePkg != null && sourcePs != null) { continue; } Slog.w(TAG, "Removing dangling permission: " + bp.getName() - + " from package " + bp.getSourcePackageName()); + + " from package " + bp.getPackageName()); mSettings.removePermissionLocked(bp.getName()); } } @@ -4243,7 +4246,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final Iterator it = mSettings.mPermissionTrees.values().iterator(); while (it.hasNext()) { final BasePermission bp = it.next(); - if (!packageName.equals(bp.getSourcePackageName())) { + if (!packageName.equals(bp.getPackageName())) { // Not checking sourcePackageSetting because it can be null when // the permission source package is the target package and the target package is // being uninstalled, @@ -4254,7 +4257,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { changed = true; if (pkg == null || !hasPermission(pkg, bp.getName())) { Slog.i(TAG, "Removing permission tree " + bp.getName() - + " that used to be declared by " + bp.getSourcePackageName()); + + " that used to be declared by " + bp.getPackageName()); it.remove(); } if (needsUpdate == null) { @@ -4266,16 +4269,16 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (needsUpdate != null) { for (final BasePermission bp : needsUpdate) { final AndroidPackage sourcePkg = - mPackageManagerInt.getPackage(bp.getSourcePackageName()); + mPackageManagerInt.getPackage(bp.getPackageName()); final PackageSetting sourcePs = (PackageSetting) mPackageManagerInt.getPackageSetting( - bp.getSourcePackageName()); + bp.getPackageName()); synchronized (mLock) { if (sourcePkg != null && sourcePs != null) { continue; } Slog.w(TAG, "Removing dangling permission tree: " + bp.getName() - + " from package " + bp.getSourcePackageName()); + + " from package " + bp.getPackageName()); mSettings.removePermissionLocked(bp.getName()); } } @@ -4888,7 +4891,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { for (int i = 0; i < numTotalPermissions; i++) { BasePermission bp = mSettings.mPermissions.valueAt(i); - if (bp.perm != null && bp.perm.getProtection() == protection) { + if (bp.getProtection() == protection) { matchingPermissions.add(bp.generatePermissionInfo(0)); } } @@ -4908,8 +4911,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { for (int i = 0; i < numTotalPermissions; i++) { BasePermission bp = mSettings.mPermissions.valueAt(i); - if (bp.perm != null && (bp.perm.getProtectionFlags() & protectionFlags) - == protectionFlags) { + if ((bp.getProtectionFlags() & protectionFlags) == protectionFlags) { matchingPermissions.add(bp.generatePermissionInfo(0)); } } diff --git a/services/core/java/com/android/server/pm/permission/UidPermissionState.java b/services/core/java/com/android/server/pm/permission/UidPermissionState.java index 38e8955e8cdb0..9727a54524409 100644 --- a/services/core/java/com/android/server/pm/permission/UidPermissionState.java +++ b/services/core/java/com/android/server/pm/permission/UidPermissionState.java @@ -284,7 +284,7 @@ public final class UidPermissionState { final PermissionState permissionState = getOrCreatePermissionState(permission); final boolean changed = permissionState.updateFlags(flagMask, flagValues); if (changed && permissionState.isDefault()) { - removePermissionState(permission.name); + removePermissionState(permission.getName()); } return changed; }