Merge "Third refactor for BasePermission."
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 667414e..6ffc598 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -16,16 +16,6 @@
 
 package com.android.server.pm.permission;
 
-import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
-import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
-import static android.content.pm.PermissionInfo.PROTECTION_NORMAL;
-import static android.content.pm.PermissionInfo.PROTECTION_SIGNATURE;
-import static android.content.pm.PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM;
-
-import static com.android.server.pm.Settings.ATTR_NAME;
-import static com.android.server.pm.Settings.ATTR_PACKAGE;
-import static com.android.server.pm.Settings.TAG_ITEM;
-
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -58,42 +48,38 @@
 import java.util.Set;
 
 public final class BasePermission {
-    static final String TAG = "PackageManager";
+    private static final String TAG = "PackageManager";
 
-    public static final int TYPE_NORMAL = 0;
-    public static final int TYPE_BUILTIN = 1;
+    public static final int TYPE_MANIFEST = 0;
+    public static final int TYPE_CONFIG = 1;
     public static final int TYPE_DYNAMIC = 2;
-    @IntDef(value = {
-        TYPE_NORMAL,
-        TYPE_BUILTIN,
-        TYPE_DYNAMIC,
+    @IntDef({
+            TYPE_MANIFEST,
+            TYPE_CONFIG,
+            TYPE_DYNAMIC,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface PermissionType {}
 
-    @IntDef(value = {
-        PROTECTION_DANGEROUS,
-        PROTECTION_NORMAL,
-        PROTECTION_SIGNATURE,
-        PROTECTION_SIGNATURE_OR_SYSTEM,
+    @IntDef({
+            PermissionInfo.PROTECTION_DANGEROUS,
+            PermissionInfo.PROTECTION_NORMAL,
+            PermissionInfo.PROTECTION_SIGNATURE,
+            PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ProtectionLevel {}
 
+    private static final String ATTR_NAME = "name";
+    private static final String ATTR_PACKAGE = "package";
+    private static final String TAG_ITEM = "item";
+
     @NonNull
-    private final String mName;
-
-    private final @PermissionType int mType;
-
-    private String mPackageName;
-
-    private int mProtectionLevel;
-
-    @Nullable
     private PermissionInfo mPermissionInfo;
 
-    @Nullable
-    private PermissionInfo mPendingPermissionInfo;
+    private boolean mReconciled;
+
+    private final @PermissionType int mType;
 
     /** UID that owns the definition of this permission */
     private int mUid;
@@ -109,30 +95,31 @@
     private boolean mGidsPerUser;
 
     public BasePermission(@NonNull String name, String packageName, @PermissionType int type) {
-        mName = name;
-        mPackageName = packageName;
-        mType = type;
+        mPermissionInfo = new PermissionInfo();
+        mPermissionInfo.name = name;
+        mPermissionInfo.packageName = packageName;
         // Default to most conservative protection level.
-        mProtectionLevel = PermissionInfo.PROTECTION_SIGNATURE;
+        mPermissionInfo.protectionLevel = PermissionInfo.PROTECTION_SIGNATURE;
+        mType = type;
     }
 
     @Override
     public String toString() {
-        return "BasePermission{" + Integer.toHexString(System.identityHashCode(this)) + " " + mName
-                + "}";
+        return "BasePermission{" + Integer.toHexString(System.identityHashCode(this)) + " "
+                + mPermissionInfo.name + "}";
     }
 
     @NonNull
     public String getName() {
-        return mName;
+        return mPermissionInfo.name;
     }
 
     public int getProtectionLevel() {
-        return mProtectionLevel;
+        return mPermissionInfo.protectionLevel;
     }
 
     public String getPackageName() {
-        return mPackageName;
+        return mPermissionInfo.packageName;
     }
 
     public int getType() {
@@ -149,7 +136,16 @@
     }
 
     public void setPermissionInfo(@Nullable PermissionInfo permissionInfo) {
-        mPermissionInfo = permissionInfo;
+        if (permissionInfo != null) {
+            mPermissionInfo = permissionInfo;
+        } else {
+            final PermissionInfo newPermissionInfo = new PermissionInfo();
+            newPermissionInfo.name = mPermissionInfo.name;
+            newPermissionInfo.packageName = mPermissionInfo.packageName;
+            newPermissionInfo.protectionLevel = mPermissionInfo.protectionLevel;
+            mPermissionInfo = newPermissionInfo;
+        }
+        mReconciled = permissionInfo != null;
     }
 
     public boolean hasGids() {
@@ -172,7 +168,7 @@
 
     public int calculateFootprint(BasePermission perm) {
         if (mUid == perm.mUid) {
-            return perm.mName.length() + perm.mPermissionInfo.calculateFootprint();
+            return perm.mPermissionInfo.name.length() + perm.mPermissionInfo.calculateFootprint();
         }
         return 0;
     }
@@ -190,128 +186,143 @@
     }
 
     public boolean isNormal() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
                 == PermissionInfo.PROTECTION_NORMAL;
     }
     public boolean isRuntime() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
                 == PermissionInfo.PROTECTION_DANGEROUS;
     }
 
     public boolean isInstalled() {
-        return mPermissionInfo != null
-                && (mPermissionInfo.flags & PermissionInfo.FLAG_INSTALLED) != 0;
+        return (mPermissionInfo.flags & PermissionInfo.FLAG_INSTALLED) != 0;
     }
 
     public boolean isRemoved() {
-        return mPermissionInfo != null
-                && (mPermissionInfo.flags & PermissionInfo.FLAG_REMOVED) != 0;
+        return (mPermissionInfo.flags & PermissionInfo.FLAG_REMOVED) != 0;
     }
 
     public boolean isSoftRestricted() {
-        return mPermissionInfo != null
-                && (mPermissionInfo.flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0;
+        return (mPermissionInfo.flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0;
     }
 
     public boolean isHardRestricted() {
-        return mPermissionInfo != null
-                && (mPermissionInfo.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0;
+        return (mPermissionInfo.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0;
     }
 
     public boolean isHardOrSoftRestricted() {
-        return mPermissionInfo != null && (mPermissionInfo.flags
-                & (PermissionInfo.FLAG_HARD_RESTRICTED | PermissionInfo.FLAG_SOFT_RESTRICTED)) != 0;
+        return (mPermissionInfo.flags & (PermissionInfo.FLAG_HARD_RESTRICTED
+                | PermissionInfo.FLAG_SOFT_RESTRICTED)) != 0;
     }
 
     public boolean isImmutablyRestricted() {
-        return mPermissionInfo != null
-                && (mPermissionInfo.flags & PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) != 0;
+        return (mPermissionInfo.flags & PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) != 0;
     }
 
     public boolean isInstallerExemptIgnored() {
-        return mPermissionInfo != null
-                && (mPermissionInfo.flags & PermissionInfo.FLAG_INSTALLER_EXEMPT_IGNORED) != 0;
+        return (mPermissionInfo.flags & PermissionInfo.FLAG_INSTALLER_EXEMPT_IGNORED) != 0;
     }
 
     public boolean isSignature() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
                 == PermissionInfo.PROTECTION_SIGNATURE;
     }
 
     public boolean isAppOp() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0;
     }
+
     public boolean isDevelopment() {
-        return isSignature()
-                && (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0;
+        return isSignature() && (mPermissionInfo.protectionLevel
+                & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0;
     }
+
     public boolean isInstaller() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0;
     }
+
     public boolean isInstant() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0;
     }
-    public boolean isOEM() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_OEM) != 0;
+
+    public boolean isOem() {
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_OEM) != 0;
     }
+
     public boolean isPre23() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_PRE23) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_PRE23) != 0;
     }
+
     public boolean isPreInstalled() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0;
     }
+
     public boolean isPrivileged() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
     }
+
     public boolean isRuntimeOnly() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0;
     }
+
     public boolean isSetup() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0;
     }
+
     public boolean isVerifier() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0;
     }
+
     public boolean isVendorPrivileged() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0;
-    }
-    public boolean isSystemTextClassifier() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER)
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED)
                 != 0;
     }
+
+    public boolean isSystemTextClassifier() {
+        return (mPermissionInfo.protectionLevel
+                & PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER) != 0;
+    }
+
     public boolean isWellbeing() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_WELLBEING) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_WELLBEING) != 0;
     }
+
     public boolean isDocumenter() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_DOCUMENTER) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_DOCUMENTER) != 0;
     }
+
     public boolean isConfigurator() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_CONFIGURATOR)
-            != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_CONFIGURATOR) != 0;
     }
+
     public boolean isIncidentReportApprover() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER) != 0;
+        return (mPermissionInfo.protectionLevel
+                & PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER) != 0;
     }
+
     public boolean isAppPredictor() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR)
+                != 0;
     }
+
     public boolean isCompanion() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0;
     }
 
     public boolean isRetailDemo() {
-        return (mProtectionLevel & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0;
+        return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0;
     }
 
     public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) {
-        if (!origPackageName.equals(mPackageName)) {
+        if (!origPackageName.equals(mPermissionInfo.packageName)) {
             return;
         }
-        mPackageName = newPackageName;
-        mPermissionInfo = null;
-        if (mPendingPermissionInfo != null) {
-            mPendingPermissionInfo.packageName = newPackageName;
-        }
+        final PermissionInfo newPermissionInfo = new PermissionInfo();
+        newPermissionInfo.name = mPermissionInfo.name;
+        newPermissionInfo.packageName = newPackageName;
+        newPermissionInfo.protectionLevel = mPermissionInfo.protectionLevel;
+        mPermissionInfo = newPermissionInfo;
+        mReconciled = false;
         mUid = 0;
         mGids = EmptyArray.INT;
         mGidsPerUser = false;
@@ -320,16 +331,16 @@
     public boolean addToTree(@ProtectionLevel int protectionLevel,
             @NonNull PermissionInfo permissionInfo, @NonNull BasePermission tree) {
         final boolean changed =
-                (mProtectionLevel != protectionLevel
-                    || mPermissionInfo == null
+                (mPermissionInfo.protectionLevel != protectionLevel
+                    || !mReconciled
                     || 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;
+        mPermissionInfo.protectionLevel = protectionLevel;
+        mReconciled = true;
         mUid = tree.mUid;
         return changed;
     }
@@ -337,13 +348,12 @@
     public void updateDynamicPermission(Collection<BasePermission> permissionTrees) {
         if (PackageManagerService.DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
                 + getName() + " pkg=" + getPackageName()
-                + " info=" + mPendingPermissionInfo);
-        if (mPendingPermissionInfo != null) {
-            final BasePermission tree = findPermissionTree(permissionTrees, mName);
-            if (tree != null && tree.mPermissionInfo != null) {
-                mPermissionInfo = new PermissionInfo(mPendingPermissionInfo);
+                + " info=" + mPermissionInfo);
+        if (mType == TYPE_DYNAMIC) {
+            final BasePermission tree = findPermissionTree(permissionTrees, mPermissionInfo.name);
+            if (tree != null) {
                 mPermissionInfo.packageName = tree.mPermissionInfo.packageName;
-                mPermissionInfo.name = mName;
+                mReconciled = true;
                 mUid = tree.mUid;
             }
         }
@@ -354,9 +364,9 @@
             @NonNull AndroidPackage pkg, Collection<BasePermission> permissionTrees,
             boolean chatty) {
         // Allow system apps to redefine non-system permissions
-        if (bp != null && !Objects.equals(bp.mPackageName, p.packageName)) {
+        if (bp != null && !Objects.equals(bp.mPermissionInfo.packageName, p.packageName)) {
             final boolean currentOwnerIsSystem;
-            if (bp.mPermissionInfo == null) {
+            if (!bp.mReconciled) {
                 currentOwnerIsSystem = false;
             } else {
                 AndroidPackage currentPackage = packageManagerInternal.getPackage(
@@ -369,34 +379,34 @@
             }
 
             if (pkg.isSystem()) {
-                if (bp.mType == BasePermission.TYPE_BUILTIN && bp.mPermissionInfo == null) {
+                if (bp.mType == BasePermission.TYPE_CONFIG && !bp.mReconciled) {
                     // It's a built-in permission and no owner, take ownership now
                     p.flags |= PermissionInfo.FLAG_INSTALLED;
                     bp.mPermissionInfo = p;
+                    bp.mReconciled = true;
                     bp.mUid = pkg.getUid();
-                    bp.mPackageName = p.packageName;
                 } else if (!currentOwnerIsSystem) {
                     String msg = "New decl " + pkg + " of permission  "
-                            + p.name + " is system; overriding " + bp.mPackageName;
+                            + p.name + " is system; overriding " + bp.mPermissionInfo.packageName;
                     PackageManagerService.reportSettingsProblem(Log.WARN, msg);
                     bp = null;
                 }
             }
         }
         if (bp == null) {
-            bp = new BasePermission(p.name, p.packageName, TYPE_NORMAL);
+            bp = new BasePermission(p.name, p.packageName, TYPE_MANIFEST);
         }
         StringBuilder r = null;
-        if (bp.mPermissionInfo == null) {
-            if (bp.mPackageName == null
-                    || bp.mPackageName.equals(p.packageName)) {
+        if (!bp.mReconciled) {
+            if (bp.mPermissionInfo.packageName == null
+                    || bp.mPermissionInfo.packageName.equals(p.packageName)) {
                 final BasePermission tree = findPermissionTree(permissionTrees, p.name);
                 if (tree == null
-                        || tree.mPackageName.equals(p.packageName)) {
+                        || tree.mPermissionInfo.packageName.equals(p.packageName)) {
                     p.flags |= PermissionInfo.FLAG_INSTALLED;
                     bp.mPermissionInfo = p;
+                    bp.mReconciled = true;
                     bp.mUid = pkg.getUid();
-                    bp.mPackageName = p.packageName;
                     if (chatty) {
                         if (r == null) {
                             r = new StringBuilder(256);
@@ -408,13 +418,13 @@
                 } else {
                     Slog.w(TAG, "Permission " + p.name + " from package "
                             + p.packageName + " ignored: base tree "
-                            + tree.mName + " is from package "
-                            + tree.mPackageName);
+                            + tree.mPermissionInfo.name + " is from package "
+                            + tree.mPermissionInfo.packageName);
                 }
             } else {
                 Slog.w(TAG, "Permission " + p.name + " from package "
                         + p.packageName + " ignored: original from "
-                        + bp.mPackageName);
+                        + bp.mPermissionInfo.packageName);
             }
         } else if (chatty) {
             if (r == null) {
@@ -425,9 +435,6 @@
             r.append("DUP:");
             r.append(p.name);
         }
-        if (bp.mPermissionInfo == p) {
-            bp.mProtectionLevel = p.protectionLevel;
-        }
         if (PackageManagerService.DEBUG_PACKAGE_SCANNING && r != null) {
             Log.d(TAG, "  Permissions: " + r);
         }
@@ -444,7 +451,7 @@
                 }
                 throw new SecurityException("Calling uid " + callingUid
                         + " is not allowed to add to permission tree "
-                        + bp.mName + " owned by uid " + bp.mUid);
+                        + bp.mPermissionInfo.name + " owned by uid " + bp.mUid);
             }
         }
         throw new SecurityException("No permission tree found for " + permName);
@@ -453,9 +460,9 @@
     private static BasePermission findPermissionTree(
             Collection<BasePermission> permissionTrees, String permName) {
         for (BasePermission bp : permissionTrees) {
-            if (permName.startsWith(bp.mName)
-                    && permName.length() > bp.mName.length()
-                    && permName.charAt(bp.mName.length()) == '.') {
+            if (permName.startsWith(bp.mPermissionInfo.name)
+                    && permName.length() > bp.mPermissionInfo.name.length()
+                    && permName.charAt(bp.mPermissionInfo.name.length()) == '.') {
                 return bp;
             }
         }
@@ -464,20 +471,20 @@
 
     @Nullable
     public String getBackgroundPermission() {
-        return mPermissionInfo != null ? mPermissionInfo.backgroundPermission : null;
+        return mPermissionInfo.backgroundPermission;
     }
 
     @Nullable
     public String getGroup() {
-        return mPermissionInfo != null ? mPermissionInfo.group : null;
+        return mPermissionInfo.group;
     }
 
     public int getProtection() {
-        return mProtectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+        return mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
     }
 
     public int getProtectionFlags() {
-        return mProtectionLevel & PermissionInfo.PROTECTION_MASK_FLAGS;
+        return mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_FLAGS;
     }
 
     @NonNull
@@ -495,17 +502,18 @@
             }
         } else {
             permissionInfo = new PermissionInfo();
-            permissionInfo.name = mName;
-            permissionInfo.packageName = mPackageName;
-            permissionInfo.nonLocalizedLabel = mName;
+            permissionInfo.name = mPermissionInfo.name;
+            permissionInfo.packageName = mPermissionInfo.packageName;
+            permissionInfo.nonLocalizedLabel = mPermissionInfo.name;
         }
         if (targetSdkVersion >= Build.VERSION_CODES.O) {
-            permissionInfo.protectionLevel = mProtectionLevel;
+            permissionInfo.protectionLevel = mPermissionInfo.protectionLevel;
         } else {
-            final int protection = mProtectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+            final int protection = mPermissionInfo.protectionLevel
+                    & PermissionInfo.PROTECTION_MASK_BASE;
             if (protection == PermissionInfo.PROTECTION_SIGNATURE) {
                 // Signature permission's protection flags are always reported.
-                permissionInfo.protectionLevel = mProtectionLevel;
+                permissionInfo.protectionLevel = mPermissionInfo.protectionLevel;
             } else {
                 permissionInfo.protectionLevel = protection;
             }
@@ -520,9 +528,9 @@
             return false;
         }
         final String name = parser.getAttributeValue(null, ATTR_NAME);
-        final String sourcePackage = parser.getAttributeValue(null, ATTR_PACKAGE);
+        final String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
         final String ptype = parser.getAttributeValue(null, "type");
-        if (name == null || sourcePackage == null) {
+        if (name == null || packageName == null) {
             PackageManagerService.reportSettingsProblem(Log.WARN,
                     "Error in package manager settings: permissions has" + " no name at "
                             + parser.getPositionDescription());
@@ -531,23 +539,19 @@
         final boolean dynamic = "dynamic".equals(ptype);
         BasePermission bp = out.get(name);
         // If the permission is builtin, do not clobber it.
-        if (bp == null || bp.mType != TYPE_BUILTIN) {
-            bp = new BasePermission(name.intern(), sourcePackage,
-                    dynamic ? TYPE_DYNAMIC : TYPE_NORMAL);
+        if (bp == null || bp.mType != TYPE_CONFIG) {
+            bp = new BasePermission(name.intern(), packageName,
+                    dynamic ? TYPE_DYNAMIC : TYPE_MANIFEST);
         }
-        bp.mProtectionLevel = readInt(parser, null, "protection",
+        bp.mPermissionInfo.protectionLevel = readInt(parser, null, "protection",
                 PermissionInfo.PROTECTION_NORMAL);
-        bp.mProtectionLevel = PermissionInfo.fixProtectionLevel(bp.mProtectionLevel);
+        bp.mPermissionInfo.protectionLevel = PermissionInfo.fixProtectionLevel(
+                bp.mPermissionInfo.protectionLevel);
         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.mProtectionLevel;
-            bp.mPendingPermissionInfo = pi;
+            bp.mPermissionInfo.icon = readInt(parser, null, "icon", 0);
+            bp.mPermissionInfo.nonLocalizedLabel = parser.getAttributeValue(null, "label");
         }
-        out.put(bp.mName, bp);
+        out.put(bp.mPermissionInfo.name, bp);
         return true;
     }
 
@@ -568,30 +572,23 @@
     }
 
     public void writeLPr(@NonNull XmlSerializer serializer) throws IOException {
-        if (mPackageName == null) {
+        if (mPermissionInfo.packageName == null) {
             return;
         }
         serializer.startTag(null, TAG_ITEM);
-        serializer.attribute(null, ATTR_NAME, mName);
-        serializer.attribute(null, ATTR_PACKAGE, mPackageName);
-        if (mProtectionLevel != PermissionInfo.PROTECTION_NORMAL) {
-            serializer.attribute(null, "protection", Integer.toString(mProtectionLevel));
+        serializer.attribute(null, ATTR_NAME, mPermissionInfo.name);
+        serializer.attribute(null, ATTR_PACKAGE, mPermissionInfo.packageName);
+        if (mPermissionInfo.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
+            serializer.attribute(null, "protection",
+                    Integer.toString(mPermissionInfo.protectionLevel));
         }
-        if (mType == BasePermission.TYPE_DYNAMIC) {
-            if (mPermissionInfo != null || mPendingPermissionInfo != null) {
-                serializer.attribute(null, "type", "dynamic");
-                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));
-                }
-                if (nonLocalizedLabel != null) {
-                    serializer.attribute(null, "label", nonLocalizedLabel.toString());
-                }
+        if (mType == TYPE_DYNAMIC) {
+            serializer.attribute(null, "type", "dynamic");
+            if (mPermissionInfo.icon != 0) {
+                serializer.attribute(null, "icon", Integer.toString(mPermissionInfo.icon));
+            }
+            if (mPermissionInfo.nonLocalizedLabel != null) {
+                serializer.attribute(null, "label", mPermissionInfo.nonLocalizedLabel.toString());
             }
         }
         serializer.endTag(null, TAG_ITEM);
@@ -616,10 +613,10 @@
     public boolean dumpPermissionsLPr(@NonNull PrintWriter pw, @NonNull String packageName,
             @NonNull Set<String> permissionNames, boolean readEnforced,
             boolean printedSomething, @NonNull DumpState dumpState) {
-        if (packageName != null && !packageName.equals(mPackageName)) {
+        if (packageName != null && !packageName.equals(mPermissionInfo.packageName)) {
             return false;
         }
-        if (permissionNames != null && !permissionNames.contains(mName)) {
+        if (permissionNames != null && !permissionNames.contains(mPermissionInfo.name)) {
             return false;
         }
         if (!printedSomething) {
@@ -627,15 +624,15 @@
                 pw.println();
             pw.println("Permissions:");
         }
-        pw.print("  Permission ["); pw.print(mName); pw.print("] (");
+        pw.print("  Permission ["); pw.print(mPermissionInfo.name); pw.print("] (");
                 pw.print(Integer.toHexString(System.identityHashCode(this)));
                 pw.println("):");
-        pw.print("    sourcePackage="); pw.println(mPackageName);
+        pw.print("    sourcePackage="); pw.println(mPermissionInfo.packageName);
         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));
+        pw.println(PermissionInfo.protectionToString(mPermissionInfo.protectionLevel));
         if (mPermissionInfo != null) {
             pw.print("    perm="); pw.println(mPermissionInfo);
             if ((mPermissionInfo.flags & PermissionInfo.FLAG_INSTALLED) == 0
@@ -643,7 +640,8 @@
                 pw.print("    flags=0x"); pw.println(Integer.toHexString(mPermissionInfo.flags));
             }
         }
-        if (READ_EXTERNAL_STORAGE.equals(mName)) {
+        if (Objects.equals(mPermissionInfo.name,
+                android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
             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 6c01017..4d439695 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -411,7 +411,7 @@
                 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
                 BasePermission bp = mSettings.getPermissionLocked(perm.name);
                 if (bp == null) {
-                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
+                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_CONFIG);
                     mSettings.putPermissionLocked(perm.name, bp);
                 }
                 if (perm.gids != null) {
@@ -3300,7 +3300,7 @@
                         PackageParser.SigningDetails.CertCapabilities.PERMISSION);
         final boolean isVendorPrivilegedPermission = bp.isVendorPrivileged();
         final boolean isPrivilegedPermission = bp.isPrivileged() || isVendorPrivilegedPermission;
-        final boolean isOemPermission = bp.isOEM();
+        final boolean isOemPermission = bp.isOem();
         if (!allowed && (isPrivilegedPermission || isOemPermission) && pkg.isSystem()) {
             final String permissionName = bp.getName();
             // For updated system applications, a privileged/oem permission