Loading core/java/android/content/pm/parsing/ParsingPackageImpl.java +2 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.content.pm.parsing.component.ParsedIntentInfo; import android.content.pm.parsing.component.ParsedMainComponent; import android.content.pm.parsing.component.ParsedPermission; import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.parsing.component.ParsedPermissionImpl; import android.content.pm.parsing.component.ParsedProcess; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedProviderImpl; Loading Loading @@ -1294,7 +1295,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.providers = ParsingUtils.createTypedInterfaceList(in, ParsedProviderImpl.CREATOR); this.attributions = ParsingUtils.createTypedInterfaceList(in, ParsedAttributionImpl.CREATOR); this.permissions = in.createTypedArrayList(ParsedPermission.CREATOR); this.permissions = ParsingUtils.createTypedInterfaceList(in, ParsedPermissionImpl.CREATOR); this.permissionGroups = in.createTypedArrayList(ParsedPermissionGroup.CREATOR); this.instrumentations = ParsingUtils.createTypedInterfaceList(in, ParsedInstrumentationImpl.CREATOR); Loading core/java/android/content/pm/parsing/component/ComponentMutateUtils.java +12 −2 Original line number Diff line number Diff line Loading @@ -46,8 +46,8 @@ public class ComponentMutateUtils { ((ParsedActivityImpl) activity).setResizeMode(resizeMode); } public static void setExactFlags(ParsedActivity activity, int exactFlags) { ((ParsedActivityImpl) activity).setFlags(exactFlags); public static void setExactFlags(ParsedComponent component, int exactFlags) { ((ParsedComponentImpl) component).setFlags(exactFlags); } public static void setEnabled(@NonNull ParsedMainComponent component, boolean enabled) { Loading Loading @@ -75,4 +75,14 @@ public class ComponentMutateUtils { public static void setSyncable(@NonNull ParsedProvider provider, boolean syncable) { ((ParsedProviderImpl) provider).setSyncable(syncable); } public static void setProtectionLevel(@NonNull ParsedPermission permission, int protectionLevel) { ((ParsedPermissionImpl) permission).setProtectionLevel(protectionLevel); } public static void setParsedPermissionGroup(@NonNull ParsedPermission permission, @NonNull ParsedPermissionGroup permissionGroup) { ((ParsedPermissionImpl) permission).setParsedPermissionGroup(permissionGroup); } } core/java/android/content/pm/parsing/component/ParsedPermission.java +9 −187 Original line number Diff line number Diff line Loading @@ -16,206 +16,28 @@ package android.content.pm.parsing.component; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.PermissionInfo; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DataClass; import com.android.internal.util.Parcelling; import com.android.internal.util.Parcelling.BuiltIn.ForInternedString; import com.android.internal.util.Parcelling.BuiltIn.ForStringSet; import java.util.Locale; import java.util.Set; /** @hide */ public class ParsedPermission extends ParsedComponentImpl { private static ForStringSet sForStringSet = Parcelling.Cache.getOrCreate(ForStringSet.class); public interface ParsedPermission extends ParsedComponent { @Nullable private String backgroundPermission; @Nullable @DataClass.ParcelWith(ForInternedString.class) private String group; private int requestRes; private int protectionLevel; private boolean tree; @Nullable private ParsedPermissionGroup parsedPermissionGroup; @Nullable private Set<String> knownCerts; @VisibleForTesting public ParsedPermission() { } public ParsedPermission(ParsedPermission other) { super(other); this.backgroundPermission = other.backgroundPermission; this.group = other.group; this.requestRes = other.requestRes; this.protectionLevel = other.protectionLevel; this.tree = other.tree; this.parsedPermissionGroup = other.parsedPermissionGroup; } public ParsedPermission setBackgroundPermission(String backgroundPermission) { this.backgroundPermission = backgroundPermission; return this; } public ParsedPermission setGroup(String group) { this.group = TextUtils.safeIntern(group); return this; } public boolean isRuntime() { return getProtection() == PermissionInfo.PROTECTION_DANGEROUS; } public boolean isAppOp() { return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; } @PermissionInfo.Protection public int getProtection() { return protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; } public int getProtectionFlags() { return protectionLevel & ~PermissionInfo.PROTECTION_MASK_BASE; } public @Nullable Set<String> getKnownCerts() { return knownCerts; } protected void setKnownCert(String knownCert) { // Convert the provided digest to upper case for consistent Set membership // checks when verifying the signing certificate digests of requesting apps. this.knownCerts = Set.of(knownCert.toUpperCase(Locale.US)); } protected void setKnownCerts(String[] knownCerts) { this.knownCerts = new ArraySet<>(); for (String knownCert : knownCerts) { this.knownCerts.add(knownCert.toUpperCase(Locale.US)); } } public int calculateFootprint() { int size = getName().length(); if (getNonLocalizedLabel() != null) { size += getNonLocalizedLabel().length(); } return size; } public ParsedPermission setKnownCerts(Set<String> knownCerts) { this.knownCerts = knownCerts; return this; } public ParsedPermission setRequestRes(int requestRes) { this.requestRes = requestRes; return this; } public ParsedPermission setTree(boolean tree) { this.tree = tree; return this; } public String toString() { return "Permission{" + Integer.toHexString(System.identityHashCode(this)) + " " + getName() + "}"; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeString(this.backgroundPermission); dest.writeString(this.group); dest.writeInt(this.requestRes); dest.writeInt(this.protectionLevel); dest.writeBoolean(this.tree); dest.writeParcelable(this.parsedPermissionGroup, flags); sForStringSet.parcel(knownCerts, dest, flags); } protected ParsedPermission(Parcel in) { super(in); // We use the boot classloader for all classes that we load. final ClassLoader boot = Object.class.getClassLoader(); this.backgroundPermission = in.readString(); this.group = in.readString(); this.requestRes = in.readInt(); this.protectionLevel = in.readInt(); this.tree = in.readBoolean(); this.parsedPermissionGroup = in.readParcelable(boot); this.knownCerts = sForStringSet.unparcel(in); } @NonNull public static final Parcelable.Creator<ParsedPermission> CREATOR = new Parcelable.Creator<ParsedPermission>() { @Override public ParsedPermission createFromParcel(Parcel source) { return new ParsedPermission(source); } @Override public ParsedPermission[] newArray(int size) { return new ParsedPermission[size]; } }; String getBackgroundPermission(); @Nullable public String getBackgroundPermission() { return backgroundPermission; } String getGroup(); @Nullable public String getGroup() { return group; } public int getRequestRes() { return requestRes; } public int getProtectionLevel() { return protectionLevel; } public boolean isTree() { return tree; } Set<String> getKnownCerts(); @Nullable public ParsedPermissionGroup getParsedPermissionGroup() { return parsedPermissionGroup; } ParsedPermissionGroup getParsedPermissionGroup(); public ParsedPermission setProtectionLevel(int value) { protectionLevel = value; return this; } int getProtectionLevel(); public ParsedPermission setParsedPermissionGroup(@Nullable ParsedPermissionGroup value) { parsedPermissionGroup = value; return this; } int getRequestRes(); boolean isTree(); } core/java/android/content/pm/parsing/component/ParsedPermissionImpl.java 0 → 100644 +255 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content.pm.parsing.component; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DataClass; import com.android.internal.util.Parcelling; import com.android.internal.util.Parcelling.BuiltIn.ForInternedString; import com.android.internal.util.Parcelling.BuiltIn.ForStringSet; import java.util.Locale; import java.util.Set; /** @hide */ @DataClass(genGetters = true, genSetters = true, genBuilder = false, genParcelable = false) @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public class ParsedPermissionImpl extends ParsedComponentImpl implements ParsedPermission { private static ForStringSet sForStringSet = Parcelling.Cache.getOrCreate(ForStringSet.class); @Nullable private String backgroundPermission; @Nullable @DataClass.ParcelWith(ForInternedString.class) private String group; private int requestRes; private int protectionLevel; private boolean tree; @Nullable private ParsedPermissionGroup parsedPermissionGroup; @Nullable private Set<String> knownCerts; @VisibleForTesting public ParsedPermissionImpl() { } public ParsedPermissionImpl(ParsedPermission other) { super(other); this.backgroundPermission = other.getBackgroundPermission(); this.group = other.getGroup(); this.requestRes = other.getRequestRes(); this.protectionLevel = other.getProtectionLevel(); this.tree = other.isTree(); this.parsedPermissionGroup = other.getParsedPermissionGroup(); } public ParsedPermissionImpl setGroup(String group) { this.group = TextUtils.safeIntern(group); return this; } protected void setKnownCert(String knownCert) { // Convert the provided digest to upper case for consistent Set membership // checks when verifying the signing certificate digests of requesting apps. this.knownCerts = Set.of(knownCert.toUpperCase(Locale.US)); } protected void setKnownCerts(String[] knownCerts) { this.knownCerts = new ArraySet<>(); for (String knownCert : knownCerts) { this.knownCerts.add(knownCert.toUpperCase(Locale.US)); } } public String toString() { return "Permission{" + Integer.toHexString(System.identityHashCode(this)) + " " + getName() + "}"; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeString(this.backgroundPermission); dest.writeString(this.group); dest.writeInt(this.requestRes); dest.writeInt(this.protectionLevel); dest.writeBoolean(this.tree); dest.writeParcelable(this.parsedPermissionGroup, flags); sForStringSet.parcel(knownCerts, dest, flags); } protected ParsedPermissionImpl(Parcel in) { super(in); // We use the boot classloader for all classes that we load. final ClassLoader boot = Object.class.getClassLoader(); this.backgroundPermission = in.readString(); this.group = TextUtils.safeIntern(in.readString()); this.requestRes = in.readInt(); this.protectionLevel = in.readInt(); this.tree = in.readBoolean(); this.parsedPermissionGroup = in.readParcelable(boot); this.knownCerts = sForStringSet.unparcel(in); } @NonNull public static final Parcelable.Creator<ParsedPermissionImpl> CREATOR = new Parcelable.Creator<ParsedPermissionImpl>() { @Override public ParsedPermissionImpl createFromParcel(Parcel source) { return new ParsedPermissionImpl(source); } @Override public ParsedPermissionImpl[] newArray(int size) { return new ParsedPermissionImpl[size]; } }; // Code below generated by codegen v1.0.23. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code // // To regenerate run: // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/parsing/component/ParsedPermissionImpl.java // // To exclude the generated code from IntelliJ auto-formatting enable (one-time): // Settings > Editor > Code Style > Formatter Control //@formatter:off @DataClass.Generated.Member public ParsedPermissionImpl( @Nullable String backgroundPermission, @Nullable String group, int requestRes, int protectionLevel, boolean tree, @Nullable ParsedPermissionGroup parsedPermissionGroup, @Nullable Set<String> knownCerts) { this.backgroundPermission = backgroundPermission; this.group = group; this.requestRes = requestRes; this.protectionLevel = protectionLevel; this.tree = tree; this.parsedPermissionGroup = parsedPermissionGroup; this.knownCerts = knownCerts; // onConstructed(); // You can define this method to get a callback } @DataClass.Generated.Member public @Nullable String getBackgroundPermission() { return backgroundPermission; } @DataClass.Generated.Member public @Nullable String getGroup() { return group; } @DataClass.Generated.Member public int getRequestRes() { return requestRes; } @DataClass.Generated.Member public int getProtectionLevel() { return protectionLevel; } @DataClass.Generated.Member public boolean isTree() { return tree; } @DataClass.Generated.Member public @Nullable ParsedPermissionGroup getParsedPermissionGroup() { return parsedPermissionGroup; } @DataClass.Generated.Member public @Nullable Set<String> getKnownCerts() { return knownCerts; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setBackgroundPermission(@NonNull String value) { backgroundPermission = value; return this; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setRequestRes( int value) { requestRes = value; return this; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setProtectionLevel( int value) { protectionLevel = value; return this; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setTree( boolean value) { tree = value; return this; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setParsedPermissionGroup(@NonNull ParsedPermissionGroup value) { parsedPermissionGroup = value; return this; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setKnownCerts(@NonNull Set<String> value) { knownCerts = value; return this; } @DataClass.Generated( time = 1627598236506L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/parsing/component/ParsedPermissionImpl.java", inputSignatures = "private static com.android.internal.util.Parcelling.BuiltIn.ForStringSet sForStringSet\nprivate @android.annotation.Nullable java.lang.String backgroundPermission\nprivate @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String group\nprivate int requestRes\nprivate int protectionLevel\nprivate boolean tree\nprivate @android.annotation.Nullable android.content.pm.parsing.component.ParsedPermissionGroup parsedPermissionGroup\nprivate @android.annotation.Nullable java.util.Set<java.lang.String> knownCerts\npublic static final @android.annotation.NonNull android.os.Parcelable.Creator<android.content.pm.parsing.component.ParsedPermissionImpl> CREATOR\npublic android.content.pm.parsing.component.ParsedPermissionImpl setGroup(java.lang.String)\nprotected void setKnownCert(java.lang.String)\nprotected void setKnownCerts(java.lang.String[])\npublic java.lang.String toString()\npublic @java.lang.Override int describeContents()\npublic @java.lang.Override void writeToParcel(android.os.Parcel,int)\nclass ParsedPermissionImpl extends android.content.pm.parsing.component.ParsedComponentImpl implements [android.content.pm.parsing.component.ParsedPermission]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=true, genBuilder=false, genParcelable=false)") @Deprecated private void __metadata() {} //@formatter:on // End of generated code } core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java +48 −14 Original line number Diff line number Diff line Loading @@ -45,10 +45,9 @@ public class ParsedPermissionUtils { XmlResourceParser parser, boolean useRoundIcon, ParseInput input) throws IOException, XmlPullParserException { String packageName = pkg.getPackageName(); ParsedPermission permission = new ParsedPermission(); ParsedPermissionImpl permission = new ParsedPermissionImpl(); String tag = "<" + parser.getName() + ">"; final ParseResult<ParsedPermission> result; ParseResult<ParsedPermissionImpl> result; TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestPermission); try { Loading @@ -62,7 +61,7 @@ public class ParsedPermissionUtils { R.styleable.AndroidManifestPermission_name, R.styleable.AndroidManifestPermission_roundIcon); if (result.isError()) { return result; return input.error(result); } if (sa.hasValue( Loading Loading @@ -121,7 +120,7 @@ public class ParsedPermissionUtils { } // For now only platform runtime permissions can be restricted if (!permission.isRuntime() || !"android".equals(permission.getPackageName())) { if (!isRuntime(permission) || !"android".equals(permission.getPackageName())) { permission.setFlags(permission.getFlags() & ~PermissionInfo.FLAG_HARD_RESTRICTED); permission.setFlags(permission.getFlags() & ~PermissionInfo.FLAG_SOFT_RESTRICTED); } else { Loading @@ -139,26 +138,31 @@ public class ParsedPermissionUtils { permission.setProtectionLevel( PermissionInfo.fixProtectionLevel(permission.getProtectionLevel())); final int otherProtectionFlags = permission.getProtectionFlags() final int otherProtectionFlags = getProtectionFlags(permission) & ~(PermissionInfo.PROTECTION_FLAG_APPOP | PermissionInfo.PROTECTION_FLAG_INSTANT | PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY); if (otherProtectionFlags != 0 && permission.getProtection() != PermissionInfo.PROTECTION_SIGNATURE && permission.getProtection() != PermissionInfo.PROTECTION_INTERNAL) { && getProtection(permission) != PermissionInfo.PROTECTION_SIGNATURE && getProtection(permission) != PermissionInfo.PROTECTION_INTERNAL) { return input.error("<permission> protectionLevel specifies a non-instant, non-appop," + " non-runtimeOnly flag but is not based on signature or internal type"); } return ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permission, input); result = ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permission, input); if (result.isError()) { return input.error(result); } return input.success(result.getResult()); } @NonNull public static ParseResult<ParsedPermission> parsePermissionTree(ParsingPackage pkg, Resources res, XmlResourceParser parser, boolean useRoundIcon, ParseInput input) throws IOException, XmlPullParserException { ParsedPermission permission = new ParsedPermission(); ParsedPermissionImpl permission = new ParsedPermissionImpl(); String tag = "<" + parser.getName() + ">"; final ParseResult<ParsedPermission> result; ParseResult<ParsedPermissionImpl> result; TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestPermissionTree); try { Loading @@ -172,7 +176,7 @@ public class ParsedPermissionUtils { R.styleable.AndroidManifestPermissionTree_name, R.styleable.AndroidManifestPermissionTree_roundIcon); if (result.isError()) { return result; return input.error(result); } } finally { sa.recycle(); Loading @@ -190,8 +194,12 @@ public class ParsedPermissionUtils { permission.setProtectionLevel(PermissionInfo.PROTECTION_NORMAL) .setTree(true); return ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permission, input); result = ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permission, input); if (result.isError()) { return input.error(result); } return input.success(result.getResult()); } @NonNull Loading Loading @@ -232,4 +240,30 @@ public class ParsedPermissionUtils { return ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permissionGroup, input); } public static boolean isRuntime(@NonNull ParsedPermission permission) { return getProtection(permission) == PermissionInfo.PROTECTION_DANGEROUS; } public static boolean isAppOp(@NonNull ParsedPermission permission) { return (permission.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; } @PermissionInfo.Protection public static int getProtection(@NonNull ParsedPermission permission) { return permission.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE; } public static int getProtectionFlags(@NonNull ParsedPermission permission) { return permission.getProtectionLevel() & ~PermissionInfo.PROTECTION_MASK_BASE; } public static int calculateFootprint(@NonNull ParsedPermission permission) { int size = permission.getName().length(); CharSequence nonLocalizedLabel = permission.getNonLocalizedLabel(); if (nonLocalizedLabel != null) { size += nonLocalizedLabel.length(); } return size; } } Loading
core/java/android/content/pm/parsing/ParsingPackageImpl.java +2 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.content.pm.parsing.component.ParsedIntentInfo; import android.content.pm.parsing.component.ParsedMainComponent; import android.content.pm.parsing.component.ParsedPermission; import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.parsing.component.ParsedPermissionImpl; import android.content.pm.parsing.component.ParsedProcess; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedProviderImpl; Loading Loading @@ -1294,7 +1295,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.providers = ParsingUtils.createTypedInterfaceList(in, ParsedProviderImpl.CREATOR); this.attributions = ParsingUtils.createTypedInterfaceList(in, ParsedAttributionImpl.CREATOR); this.permissions = in.createTypedArrayList(ParsedPermission.CREATOR); this.permissions = ParsingUtils.createTypedInterfaceList(in, ParsedPermissionImpl.CREATOR); this.permissionGroups = in.createTypedArrayList(ParsedPermissionGroup.CREATOR); this.instrumentations = ParsingUtils.createTypedInterfaceList(in, ParsedInstrumentationImpl.CREATOR); Loading
core/java/android/content/pm/parsing/component/ComponentMutateUtils.java +12 −2 Original line number Diff line number Diff line Loading @@ -46,8 +46,8 @@ public class ComponentMutateUtils { ((ParsedActivityImpl) activity).setResizeMode(resizeMode); } public static void setExactFlags(ParsedActivity activity, int exactFlags) { ((ParsedActivityImpl) activity).setFlags(exactFlags); public static void setExactFlags(ParsedComponent component, int exactFlags) { ((ParsedComponentImpl) component).setFlags(exactFlags); } public static void setEnabled(@NonNull ParsedMainComponent component, boolean enabled) { Loading Loading @@ -75,4 +75,14 @@ public class ComponentMutateUtils { public static void setSyncable(@NonNull ParsedProvider provider, boolean syncable) { ((ParsedProviderImpl) provider).setSyncable(syncable); } public static void setProtectionLevel(@NonNull ParsedPermission permission, int protectionLevel) { ((ParsedPermissionImpl) permission).setProtectionLevel(protectionLevel); } public static void setParsedPermissionGroup(@NonNull ParsedPermission permission, @NonNull ParsedPermissionGroup permissionGroup) { ((ParsedPermissionImpl) permission).setParsedPermissionGroup(permissionGroup); } }
core/java/android/content/pm/parsing/component/ParsedPermission.java +9 −187 Original line number Diff line number Diff line Loading @@ -16,206 +16,28 @@ package android.content.pm.parsing.component; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.PermissionInfo; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DataClass; import com.android.internal.util.Parcelling; import com.android.internal.util.Parcelling.BuiltIn.ForInternedString; import com.android.internal.util.Parcelling.BuiltIn.ForStringSet; import java.util.Locale; import java.util.Set; /** @hide */ public class ParsedPermission extends ParsedComponentImpl { private static ForStringSet sForStringSet = Parcelling.Cache.getOrCreate(ForStringSet.class); public interface ParsedPermission extends ParsedComponent { @Nullable private String backgroundPermission; @Nullable @DataClass.ParcelWith(ForInternedString.class) private String group; private int requestRes; private int protectionLevel; private boolean tree; @Nullable private ParsedPermissionGroup parsedPermissionGroup; @Nullable private Set<String> knownCerts; @VisibleForTesting public ParsedPermission() { } public ParsedPermission(ParsedPermission other) { super(other); this.backgroundPermission = other.backgroundPermission; this.group = other.group; this.requestRes = other.requestRes; this.protectionLevel = other.protectionLevel; this.tree = other.tree; this.parsedPermissionGroup = other.parsedPermissionGroup; } public ParsedPermission setBackgroundPermission(String backgroundPermission) { this.backgroundPermission = backgroundPermission; return this; } public ParsedPermission setGroup(String group) { this.group = TextUtils.safeIntern(group); return this; } public boolean isRuntime() { return getProtection() == PermissionInfo.PROTECTION_DANGEROUS; } public boolean isAppOp() { return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; } @PermissionInfo.Protection public int getProtection() { return protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; } public int getProtectionFlags() { return protectionLevel & ~PermissionInfo.PROTECTION_MASK_BASE; } public @Nullable Set<String> getKnownCerts() { return knownCerts; } protected void setKnownCert(String knownCert) { // Convert the provided digest to upper case for consistent Set membership // checks when verifying the signing certificate digests of requesting apps. this.knownCerts = Set.of(knownCert.toUpperCase(Locale.US)); } protected void setKnownCerts(String[] knownCerts) { this.knownCerts = new ArraySet<>(); for (String knownCert : knownCerts) { this.knownCerts.add(knownCert.toUpperCase(Locale.US)); } } public int calculateFootprint() { int size = getName().length(); if (getNonLocalizedLabel() != null) { size += getNonLocalizedLabel().length(); } return size; } public ParsedPermission setKnownCerts(Set<String> knownCerts) { this.knownCerts = knownCerts; return this; } public ParsedPermission setRequestRes(int requestRes) { this.requestRes = requestRes; return this; } public ParsedPermission setTree(boolean tree) { this.tree = tree; return this; } public String toString() { return "Permission{" + Integer.toHexString(System.identityHashCode(this)) + " " + getName() + "}"; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeString(this.backgroundPermission); dest.writeString(this.group); dest.writeInt(this.requestRes); dest.writeInt(this.protectionLevel); dest.writeBoolean(this.tree); dest.writeParcelable(this.parsedPermissionGroup, flags); sForStringSet.parcel(knownCerts, dest, flags); } protected ParsedPermission(Parcel in) { super(in); // We use the boot classloader for all classes that we load. final ClassLoader boot = Object.class.getClassLoader(); this.backgroundPermission = in.readString(); this.group = in.readString(); this.requestRes = in.readInt(); this.protectionLevel = in.readInt(); this.tree = in.readBoolean(); this.parsedPermissionGroup = in.readParcelable(boot); this.knownCerts = sForStringSet.unparcel(in); } @NonNull public static final Parcelable.Creator<ParsedPermission> CREATOR = new Parcelable.Creator<ParsedPermission>() { @Override public ParsedPermission createFromParcel(Parcel source) { return new ParsedPermission(source); } @Override public ParsedPermission[] newArray(int size) { return new ParsedPermission[size]; } }; String getBackgroundPermission(); @Nullable public String getBackgroundPermission() { return backgroundPermission; } String getGroup(); @Nullable public String getGroup() { return group; } public int getRequestRes() { return requestRes; } public int getProtectionLevel() { return protectionLevel; } public boolean isTree() { return tree; } Set<String> getKnownCerts(); @Nullable public ParsedPermissionGroup getParsedPermissionGroup() { return parsedPermissionGroup; } ParsedPermissionGroup getParsedPermissionGroup(); public ParsedPermission setProtectionLevel(int value) { protectionLevel = value; return this; } int getProtectionLevel(); public ParsedPermission setParsedPermissionGroup(@Nullable ParsedPermissionGroup value) { parsedPermissionGroup = value; return this; } int getRequestRes(); boolean isTree(); }
core/java/android/content/pm/parsing/component/ParsedPermissionImpl.java 0 → 100644 +255 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content.pm.parsing.component; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DataClass; import com.android.internal.util.Parcelling; import com.android.internal.util.Parcelling.BuiltIn.ForInternedString; import com.android.internal.util.Parcelling.BuiltIn.ForStringSet; import java.util.Locale; import java.util.Set; /** @hide */ @DataClass(genGetters = true, genSetters = true, genBuilder = false, genParcelable = false) @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public class ParsedPermissionImpl extends ParsedComponentImpl implements ParsedPermission { private static ForStringSet sForStringSet = Parcelling.Cache.getOrCreate(ForStringSet.class); @Nullable private String backgroundPermission; @Nullable @DataClass.ParcelWith(ForInternedString.class) private String group; private int requestRes; private int protectionLevel; private boolean tree; @Nullable private ParsedPermissionGroup parsedPermissionGroup; @Nullable private Set<String> knownCerts; @VisibleForTesting public ParsedPermissionImpl() { } public ParsedPermissionImpl(ParsedPermission other) { super(other); this.backgroundPermission = other.getBackgroundPermission(); this.group = other.getGroup(); this.requestRes = other.getRequestRes(); this.protectionLevel = other.getProtectionLevel(); this.tree = other.isTree(); this.parsedPermissionGroup = other.getParsedPermissionGroup(); } public ParsedPermissionImpl setGroup(String group) { this.group = TextUtils.safeIntern(group); return this; } protected void setKnownCert(String knownCert) { // Convert the provided digest to upper case for consistent Set membership // checks when verifying the signing certificate digests of requesting apps. this.knownCerts = Set.of(knownCert.toUpperCase(Locale.US)); } protected void setKnownCerts(String[] knownCerts) { this.knownCerts = new ArraySet<>(); for (String knownCert : knownCerts) { this.knownCerts.add(knownCert.toUpperCase(Locale.US)); } } public String toString() { return "Permission{" + Integer.toHexString(System.identityHashCode(this)) + " " + getName() + "}"; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeString(this.backgroundPermission); dest.writeString(this.group); dest.writeInt(this.requestRes); dest.writeInt(this.protectionLevel); dest.writeBoolean(this.tree); dest.writeParcelable(this.parsedPermissionGroup, flags); sForStringSet.parcel(knownCerts, dest, flags); } protected ParsedPermissionImpl(Parcel in) { super(in); // We use the boot classloader for all classes that we load. final ClassLoader boot = Object.class.getClassLoader(); this.backgroundPermission = in.readString(); this.group = TextUtils.safeIntern(in.readString()); this.requestRes = in.readInt(); this.protectionLevel = in.readInt(); this.tree = in.readBoolean(); this.parsedPermissionGroup = in.readParcelable(boot); this.knownCerts = sForStringSet.unparcel(in); } @NonNull public static final Parcelable.Creator<ParsedPermissionImpl> CREATOR = new Parcelable.Creator<ParsedPermissionImpl>() { @Override public ParsedPermissionImpl createFromParcel(Parcel source) { return new ParsedPermissionImpl(source); } @Override public ParsedPermissionImpl[] newArray(int size) { return new ParsedPermissionImpl[size]; } }; // Code below generated by codegen v1.0.23. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code // // To regenerate run: // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/parsing/component/ParsedPermissionImpl.java // // To exclude the generated code from IntelliJ auto-formatting enable (one-time): // Settings > Editor > Code Style > Formatter Control //@formatter:off @DataClass.Generated.Member public ParsedPermissionImpl( @Nullable String backgroundPermission, @Nullable String group, int requestRes, int protectionLevel, boolean tree, @Nullable ParsedPermissionGroup parsedPermissionGroup, @Nullable Set<String> knownCerts) { this.backgroundPermission = backgroundPermission; this.group = group; this.requestRes = requestRes; this.protectionLevel = protectionLevel; this.tree = tree; this.parsedPermissionGroup = parsedPermissionGroup; this.knownCerts = knownCerts; // onConstructed(); // You can define this method to get a callback } @DataClass.Generated.Member public @Nullable String getBackgroundPermission() { return backgroundPermission; } @DataClass.Generated.Member public @Nullable String getGroup() { return group; } @DataClass.Generated.Member public int getRequestRes() { return requestRes; } @DataClass.Generated.Member public int getProtectionLevel() { return protectionLevel; } @DataClass.Generated.Member public boolean isTree() { return tree; } @DataClass.Generated.Member public @Nullable ParsedPermissionGroup getParsedPermissionGroup() { return parsedPermissionGroup; } @DataClass.Generated.Member public @Nullable Set<String> getKnownCerts() { return knownCerts; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setBackgroundPermission(@NonNull String value) { backgroundPermission = value; return this; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setRequestRes( int value) { requestRes = value; return this; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setProtectionLevel( int value) { protectionLevel = value; return this; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setTree( boolean value) { tree = value; return this; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setParsedPermissionGroup(@NonNull ParsedPermissionGroup value) { parsedPermissionGroup = value; return this; } @DataClass.Generated.Member public @NonNull ParsedPermissionImpl setKnownCerts(@NonNull Set<String> value) { knownCerts = value; return this; } @DataClass.Generated( time = 1627598236506L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/parsing/component/ParsedPermissionImpl.java", inputSignatures = "private static com.android.internal.util.Parcelling.BuiltIn.ForStringSet sForStringSet\nprivate @android.annotation.Nullable java.lang.String backgroundPermission\nprivate @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String group\nprivate int requestRes\nprivate int protectionLevel\nprivate boolean tree\nprivate @android.annotation.Nullable android.content.pm.parsing.component.ParsedPermissionGroup parsedPermissionGroup\nprivate @android.annotation.Nullable java.util.Set<java.lang.String> knownCerts\npublic static final @android.annotation.NonNull android.os.Parcelable.Creator<android.content.pm.parsing.component.ParsedPermissionImpl> CREATOR\npublic android.content.pm.parsing.component.ParsedPermissionImpl setGroup(java.lang.String)\nprotected void setKnownCert(java.lang.String)\nprotected void setKnownCerts(java.lang.String[])\npublic java.lang.String toString()\npublic @java.lang.Override int describeContents()\npublic @java.lang.Override void writeToParcel(android.os.Parcel,int)\nclass ParsedPermissionImpl extends android.content.pm.parsing.component.ParsedComponentImpl implements [android.content.pm.parsing.component.ParsedPermission]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=true, genBuilder=false, genParcelable=false)") @Deprecated private void __metadata() {} //@formatter:on // End of generated code }
core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java +48 −14 Original line number Diff line number Diff line Loading @@ -45,10 +45,9 @@ public class ParsedPermissionUtils { XmlResourceParser parser, boolean useRoundIcon, ParseInput input) throws IOException, XmlPullParserException { String packageName = pkg.getPackageName(); ParsedPermission permission = new ParsedPermission(); ParsedPermissionImpl permission = new ParsedPermissionImpl(); String tag = "<" + parser.getName() + ">"; final ParseResult<ParsedPermission> result; ParseResult<ParsedPermissionImpl> result; TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestPermission); try { Loading @@ -62,7 +61,7 @@ public class ParsedPermissionUtils { R.styleable.AndroidManifestPermission_name, R.styleable.AndroidManifestPermission_roundIcon); if (result.isError()) { return result; return input.error(result); } if (sa.hasValue( Loading Loading @@ -121,7 +120,7 @@ public class ParsedPermissionUtils { } // For now only platform runtime permissions can be restricted if (!permission.isRuntime() || !"android".equals(permission.getPackageName())) { if (!isRuntime(permission) || !"android".equals(permission.getPackageName())) { permission.setFlags(permission.getFlags() & ~PermissionInfo.FLAG_HARD_RESTRICTED); permission.setFlags(permission.getFlags() & ~PermissionInfo.FLAG_SOFT_RESTRICTED); } else { Loading @@ -139,26 +138,31 @@ public class ParsedPermissionUtils { permission.setProtectionLevel( PermissionInfo.fixProtectionLevel(permission.getProtectionLevel())); final int otherProtectionFlags = permission.getProtectionFlags() final int otherProtectionFlags = getProtectionFlags(permission) & ~(PermissionInfo.PROTECTION_FLAG_APPOP | PermissionInfo.PROTECTION_FLAG_INSTANT | PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY); if (otherProtectionFlags != 0 && permission.getProtection() != PermissionInfo.PROTECTION_SIGNATURE && permission.getProtection() != PermissionInfo.PROTECTION_INTERNAL) { && getProtection(permission) != PermissionInfo.PROTECTION_SIGNATURE && getProtection(permission) != PermissionInfo.PROTECTION_INTERNAL) { return input.error("<permission> protectionLevel specifies a non-instant, non-appop," + " non-runtimeOnly flag but is not based on signature or internal type"); } return ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permission, input); result = ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permission, input); if (result.isError()) { return input.error(result); } return input.success(result.getResult()); } @NonNull public static ParseResult<ParsedPermission> parsePermissionTree(ParsingPackage pkg, Resources res, XmlResourceParser parser, boolean useRoundIcon, ParseInput input) throws IOException, XmlPullParserException { ParsedPermission permission = new ParsedPermission(); ParsedPermissionImpl permission = new ParsedPermissionImpl(); String tag = "<" + parser.getName() + ">"; final ParseResult<ParsedPermission> result; ParseResult<ParsedPermissionImpl> result; TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestPermissionTree); try { Loading @@ -172,7 +176,7 @@ public class ParsedPermissionUtils { R.styleable.AndroidManifestPermissionTree_name, R.styleable.AndroidManifestPermissionTree_roundIcon); if (result.isError()) { return result; return input.error(result); } } finally { sa.recycle(); Loading @@ -190,8 +194,12 @@ public class ParsedPermissionUtils { permission.setProtectionLevel(PermissionInfo.PROTECTION_NORMAL) .setTree(true); return ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permission, input); result = ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permission, input); if (result.isError()) { return input.error(result); } return input.success(result.getResult()); } @NonNull Loading Loading @@ -232,4 +240,30 @@ public class ParsedPermissionUtils { return ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permissionGroup, input); } public static boolean isRuntime(@NonNull ParsedPermission permission) { return getProtection(permission) == PermissionInfo.PROTECTION_DANGEROUS; } public static boolean isAppOp(@NonNull ParsedPermission permission) { return (permission.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; } @PermissionInfo.Protection public static int getProtection(@NonNull ParsedPermission permission) { return permission.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE; } public static int getProtectionFlags(@NonNull ParsedPermission permission) { return permission.getProtectionLevel() & ~PermissionInfo.PROTECTION_MASK_BASE; } public static int calculateFootprint(@NonNull ParsedPermission permission) { int size = permission.getName().length(); CharSequence nonLocalizedLabel = permission.getNonLocalizedLabel(); if (nonLocalizedLabel != null) { size += nonLocalizedLabel.length(); } return size; } }