Loading core/java/android/content/pm/parsing/ParsingPackage.java +2 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.parsing.component.ParsedProcess; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; import android.content.pm.parsing.component.ParsedUsesPermission; import android.os.Bundle; import android.util.SparseArray; import android.util.SparseIntArray; Loading Loading @@ -89,7 +90,7 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage addReqFeature(FeatureInfo reqFeature); ParsingPackage addRequestedPermission(String permission); ParsingPackage addUsesPermission(ParsedUsesPermission parsedUsesPermission); ParsingPackage addService(ParsedService parsedService); Loading core/java/android/content/pm/parsing/ParsingPackageImpl.java +20 −7 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.parsing.component.ParsedProcess; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; import android.content.pm.parsing.component.ParsedUsesPermission; import android.content.res.TypedArray; import android.os.Build; import android.os.Bundle; Loading Loading @@ -71,6 +72,7 @@ import com.android.internal.util.Parcelling.BuiltIn.ForInternedStringValueMap; import com.android.internal.util.Parcelling.BuiltIn.ForStringSet; import java.security.PublicKey; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; Loading Loading @@ -227,8 +229,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { protected List<String> adoptPermissions = emptyList(); @NonNull @DataClass.ParcelWith(ForInternedStringList.class) private List<String> requestedPermissions = emptyList(); private List<ParsedUsesPermission> usesPermissions = emptyList(); @NonNull @DataClass.ParcelWith(ForInternedStringList.class) private List<String> implicitPermissions = emptyList(); Loading Loading @@ -691,9 +693,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { } @Override public ParsingPackageImpl addRequestedPermission(String permission) { this.requestedPermissions = CollectionUtils.add(this.requestedPermissions, TextUtils.safeIntern(permission)); public ParsingPackageImpl addUsesPermission(ParsedUsesPermission permission) { this.usesPermissions = CollectionUtils.add(this.usesPermissions, permission); return this; } Loading Loading @@ -1134,7 +1135,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { dest.writeByteArray(this.restrictUpdateHash); dest.writeStringList(this.originalPackages); sForInternedStringList.parcel(this.adoptPermissions, dest, flags); sForInternedStringList.parcel(this.requestedPermissions, dest, flags); dest.writeTypedList(this.usesPermissions); sForInternedStringList.parcel(this.implicitPermissions, dest, flags); sForStringSet.parcel(this.upgradeKeySets, dest, flags); dest.writeMap(this.keySetMapping); Loading Loading @@ -1255,7 +1256,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.restrictUpdateHash = in.createByteArray(); this.originalPackages = in.createStringArrayList(); this.adoptPermissions = sForInternedStringList.unparcel(in); this.requestedPermissions = sForInternedStringList.unparcel(in); this.usesPermissions = in.createTypedArrayList(ParsedUsesPermission.CREATOR); this.implicitPermissions = sForInternedStringList.unparcel(in); this.upgradeKeySets = sForStringSet.unparcel(in); this.keySetMapping = in.readHashMap(boot); Loading Loading @@ -1551,9 +1552,21 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { @NonNull @Override public List<String> getRequestedPermissions() { final List<ParsedUsesPermission> usesPermissions = getUsesPermissions(); final int size = usesPermissions.size(); final List<String> requestedPermissions = new ArrayList<>(size); for (int i = 0; i < size; i++) { requestedPermissions.add(usesPermissions.get(i).name); } return requestedPermissions; } @NonNull @Override public List<ParsedUsesPermission> getUsesPermissions() { return usesPermissions; } @NonNull @Override public List<String> getImplicitPermissions() { Loading core/java/android/content/pm/parsing/ParsingPackageRead.java +11 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.parsing.component.ParsedProcess; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; import android.content.pm.parsing.component.ParsedUsesPermission; import android.os.Bundle; import android.os.Parcelable; import android.util.ArraySet; Loading @@ -45,6 +46,7 @@ import android.util.SparseArray; import android.util.SparseIntArray; import java.security.PublicKey; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; Loading Loading @@ -192,6 +194,14 @@ public interface ParsingPackageRead extends Parcelable { @NonNull List<FeatureInfo> getReqFeatures(); /** * @deprecated consider migrating to {@link #getUsesPermissions} which has * more parsed details, such as flags */ @NonNull @Deprecated List<String> getRequestedPermissions(); /** * All the permissions declared. This is an effective set, and may include permissions * transformed from split/migrated permissions from previous versions, so may not be exactly Loading @@ -200,7 +210,7 @@ public interface ParsingPackageRead extends Parcelable { * @see R.styleable#AndroidManifestUsesPermission */ @NonNull List<String> getRequestedPermissions(); List<ParsedUsesPermission> getUsesPermissions(); /** * Returns the properties set on the application Loading core/java/android/content/pm/parsing/ParsingPackageUtils.java +31 −8 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedProviderUtils; import android.content.pm.parsing.component.ParsedService; import android.content.pm.parsing.component.ParsedServiceUtils; import android.content.pm.parsing.component.ParsedUsesPermission; import android.content.pm.parsing.result.ParseInput; import android.content.pm.parsing.result.ParseInput.DeferredError; import android.content.pm.parsing.result.ParseResult; Loading Loading @@ -119,6 +120,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.StringTokenizer; Loading Loading @@ -1206,6 +1208,10 @@ public class ParsingPackageUtils { requiredNotFeatures.add(feature); } final int usesPermissionFlags = sa.getInt( com.android.internal.R.styleable.AndroidManifestUsesPermission_usesPermissionFlags, 0); final int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT Loading Loading @@ -1270,14 +1276,31 @@ public class ParsingPackageUtils { } } if (!pkg.getRequestedPermissions().contains(name)) { pkg.addRequestedPermission(name.intern()); // Quietly ignore duplicate permission requests, but fail loudly if // the two requests have conflicting flags boolean found = false; final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions(); final int size = usesPermissions.size(); for (int i = 0; i < size; i++) { final ParsedUsesPermission usesPermission = usesPermissions.get(i); if (Objects.equals(usesPermission.name, name)) { if (usesPermission.usesPermissionFlags != usesPermissionFlags) { return input.error("Conflicting uses-permissions flags: " + name + " in package: " + pkg.getPackageName() + " at: " + parser.getPositionDescription()); } else { Slog.w(TAG, "Ignoring duplicate uses-permissions/uses-permissions-sdk-m: " + name + " in package: " + pkg.getPackageName() + " at: " + parser.getPositionDescription()); } found = true; break; } } if (!found) { pkg.addUsesPermission(new ParsedUsesPermission(name, usesPermissionFlags)); } return success; } finally { sa.recycle(); Loading Loading @@ -2755,7 +2778,7 @@ public class ParsingPackageUtils { newPermsMsg.append(' '); } newPermsMsg.append(npi.name); pkg.addRequestedPermission(npi.name) pkg.addUsesPermission(new ParsedUsesPermission(npi.name, 0)) .addImplicitPermission(npi.name); } } Loading @@ -2777,7 +2800,7 @@ public class ParsingPackageUtils { for (int in = 0; in < newPerms.size(); in++) { final String perm = newPerms.get(in); if (!requestedPermissions.contains(perm)) { pkg.addRequestedPermission(perm) pkg.addUsesPermission(new ParsedUsesPermission(perm, 0)) .addImplicitPermission(perm); } } Loading core/java/android/content/pm/parsing/component/ParsedUsesPermission.java 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 static android.content.pm.parsing.ParsingPackageImpl.sForInternedString; import android.annotation.IntDef; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * A {@link android.R.styleable#AndroidManifestUsesPermission * <uses-permission>} tag parsed from the manifest. * * @hide */ public class ParsedUsesPermission implements Parcelable { /** Name of the permission requested */ public @NonNull String name; /** Set of flags that should apply to this permission request. */ public @UsesPermissionFlags int usesPermissionFlags; /** * Strong assertion by a developer that they will never use this permission * to derive the physical location of the device, regardless of * ACCESS_FINE_LOCATION and/or ACCESS_COARSE_LOCATION being granted. */ public static final int FLAG_NEVER_FOR_LOCATION = 0x1; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "FLAG_" }, value = { FLAG_NEVER_FOR_LOCATION }) public @interface UsesPermissionFlags {} public ParsedUsesPermission(@NonNull String name, @UsesPermissionFlags int usesPermissionFlags) { this.name = name.intern(); this.usesPermissionFlags = usesPermissionFlags; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { sForInternedString.parcel(this.name, dest, flags); dest.writeInt(usesPermissionFlags); } @Override public int describeContents() { return 0; } protected ParsedUsesPermission(@NonNull Parcel in) { this.name = sForInternedString.unparcel(in); this.usesPermissionFlags = in.readInt(); } public static final @NonNull Parcelable.Creator<ParsedUsesPermission> CREATOR = new Parcelable.Creator<ParsedUsesPermission>() { @Override public ParsedUsesPermission[] newArray(int size) { return new ParsedUsesPermission[size]; } @Override public ParsedUsesPermission createFromParcel(@NonNull Parcel in) { return new ParsedUsesPermission(in); } }; } Loading
core/java/android/content/pm/parsing/ParsingPackage.java +2 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.parsing.component.ParsedProcess; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; import android.content.pm.parsing.component.ParsedUsesPermission; import android.os.Bundle; import android.util.SparseArray; import android.util.SparseIntArray; Loading Loading @@ -89,7 +90,7 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage addReqFeature(FeatureInfo reqFeature); ParsingPackage addRequestedPermission(String permission); ParsingPackage addUsesPermission(ParsedUsesPermission parsedUsesPermission); ParsingPackage addService(ParsedService parsedService); Loading
core/java/android/content/pm/parsing/ParsingPackageImpl.java +20 −7 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.parsing.component.ParsedProcess; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; import android.content.pm.parsing.component.ParsedUsesPermission; import android.content.res.TypedArray; import android.os.Build; import android.os.Bundle; Loading Loading @@ -71,6 +72,7 @@ import com.android.internal.util.Parcelling.BuiltIn.ForInternedStringValueMap; import com.android.internal.util.Parcelling.BuiltIn.ForStringSet; import java.security.PublicKey; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; Loading Loading @@ -227,8 +229,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { protected List<String> adoptPermissions = emptyList(); @NonNull @DataClass.ParcelWith(ForInternedStringList.class) private List<String> requestedPermissions = emptyList(); private List<ParsedUsesPermission> usesPermissions = emptyList(); @NonNull @DataClass.ParcelWith(ForInternedStringList.class) private List<String> implicitPermissions = emptyList(); Loading Loading @@ -691,9 +693,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { } @Override public ParsingPackageImpl addRequestedPermission(String permission) { this.requestedPermissions = CollectionUtils.add(this.requestedPermissions, TextUtils.safeIntern(permission)); public ParsingPackageImpl addUsesPermission(ParsedUsesPermission permission) { this.usesPermissions = CollectionUtils.add(this.usesPermissions, permission); return this; } Loading Loading @@ -1134,7 +1135,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { dest.writeByteArray(this.restrictUpdateHash); dest.writeStringList(this.originalPackages); sForInternedStringList.parcel(this.adoptPermissions, dest, flags); sForInternedStringList.parcel(this.requestedPermissions, dest, flags); dest.writeTypedList(this.usesPermissions); sForInternedStringList.parcel(this.implicitPermissions, dest, flags); sForStringSet.parcel(this.upgradeKeySets, dest, flags); dest.writeMap(this.keySetMapping); Loading Loading @@ -1255,7 +1256,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.restrictUpdateHash = in.createByteArray(); this.originalPackages = in.createStringArrayList(); this.adoptPermissions = sForInternedStringList.unparcel(in); this.requestedPermissions = sForInternedStringList.unparcel(in); this.usesPermissions = in.createTypedArrayList(ParsedUsesPermission.CREATOR); this.implicitPermissions = sForInternedStringList.unparcel(in); this.upgradeKeySets = sForStringSet.unparcel(in); this.keySetMapping = in.readHashMap(boot); Loading Loading @@ -1551,9 +1552,21 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { @NonNull @Override public List<String> getRequestedPermissions() { final List<ParsedUsesPermission> usesPermissions = getUsesPermissions(); final int size = usesPermissions.size(); final List<String> requestedPermissions = new ArrayList<>(size); for (int i = 0; i < size; i++) { requestedPermissions.add(usesPermissions.get(i).name); } return requestedPermissions; } @NonNull @Override public List<ParsedUsesPermission> getUsesPermissions() { return usesPermissions; } @NonNull @Override public List<String> getImplicitPermissions() { Loading
core/java/android/content/pm/parsing/ParsingPackageRead.java +11 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.parsing.component.ParsedProcess; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; import android.content.pm.parsing.component.ParsedUsesPermission; import android.os.Bundle; import android.os.Parcelable; import android.util.ArraySet; Loading @@ -45,6 +46,7 @@ import android.util.SparseArray; import android.util.SparseIntArray; import java.security.PublicKey; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; Loading Loading @@ -192,6 +194,14 @@ public interface ParsingPackageRead extends Parcelable { @NonNull List<FeatureInfo> getReqFeatures(); /** * @deprecated consider migrating to {@link #getUsesPermissions} which has * more parsed details, such as flags */ @NonNull @Deprecated List<String> getRequestedPermissions(); /** * All the permissions declared. This is an effective set, and may include permissions * transformed from split/migrated permissions from previous versions, so may not be exactly Loading @@ -200,7 +210,7 @@ public interface ParsingPackageRead extends Parcelable { * @see R.styleable#AndroidManifestUsesPermission */ @NonNull List<String> getRequestedPermissions(); List<ParsedUsesPermission> getUsesPermissions(); /** * Returns the properties set on the application Loading
core/java/android/content/pm/parsing/ParsingPackageUtils.java +31 −8 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedProviderUtils; import android.content.pm.parsing.component.ParsedService; import android.content.pm.parsing.component.ParsedServiceUtils; import android.content.pm.parsing.component.ParsedUsesPermission; import android.content.pm.parsing.result.ParseInput; import android.content.pm.parsing.result.ParseInput.DeferredError; import android.content.pm.parsing.result.ParseResult; Loading Loading @@ -119,6 +120,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.StringTokenizer; Loading Loading @@ -1206,6 +1208,10 @@ public class ParsingPackageUtils { requiredNotFeatures.add(feature); } final int usesPermissionFlags = sa.getInt( com.android.internal.R.styleable.AndroidManifestUsesPermission_usesPermissionFlags, 0); final int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT Loading Loading @@ -1270,14 +1276,31 @@ public class ParsingPackageUtils { } } if (!pkg.getRequestedPermissions().contains(name)) { pkg.addRequestedPermission(name.intern()); // Quietly ignore duplicate permission requests, but fail loudly if // the two requests have conflicting flags boolean found = false; final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions(); final int size = usesPermissions.size(); for (int i = 0; i < size; i++) { final ParsedUsesPermission usesPermission = usesPermissions.get(i); if (Objects.equals(usesPermission.name, name)) { if (usesPermission.usesPermissionFlags != usesPermissionFlags) { return input.error("Conflicting uses-permissions flags: " + name + " in package: " + pkg.getPackageName() + " at: " + parser.getPositionDescription()); } else { Slog.w(TAG, "Ignoring duplicate uses-permissions/uses-permissions-sdk-m: " + name + " in package: " + pkg.getPackageName() + " at: " + parser.getPositionDescription()); } found = true; break; } } if (!found) { pkg.addUsesPermission(new ParsedUsesPermission(name, usesPermissionFlags)); } return success; } finally { sa.recycle(); Loading Loading @@ -2755,7 +2778,7 @@ public class ParsingPackageUtils { newPermsMsg.append(' '); } newPermsMsg.append(npi.name); pkg.addRequestedPermission(npi.name) pkg.addUsesPermission(new ParsedUsesPermission(npi.name, 0)) .addImplicitPermission(npi.name); } } Loading @@ -2777,7 +2800,7 @@ public class ParsingPackageUtils { for (int in = 0; in < newPerms.size(); in++) { final String perm = newPerms.get(in); if (!requestedPermissions.contains(perm)) { pkg.addRequestedPermission(perm) pkg.addUsesPermission(new ParsedUsesPermission(perm, 0)) .addImplicitPermission(perm); } } Loading
core/java/android/content/pm/parsing/component/ParsedUsesPermission.java 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 static android.content.pm.parsing.ParsingPackageImpl.sForInternedString; import android.annotation.IntDef; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * A {@link android.R.styleable#AndroidManifestUsesPermission * <uses-permission>} tag parsed from the manifest. * * @hide */ public class ParsedUsesPermission implements Parcelable { /** Name of the permission requested */ public @NonNull String name; /** Set of flags that should apply to this permission request. */ public @UsesPermissionFlags int usesPermissionFlags; /** * Strong assertion by a developer that they will never use this permission * to derive the physical location of the device, regardless of * ACCESS_FINE_LOCATION and/or ACCESS_COARSE_LOCATION being granted. */ public static final int FLAG_NEVER_FOR_LOCATION = 0x1; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "FLAG_" }, value = { FLAG_NEVER_FOR_LOCATION }) public @interface UsesPermissionFlags {} public ParsedUsesPermission(@NonNull String name, @UsesPermissionFlags int usesPermissionFlags) { this.name = name.intern(); this.usesPermissionFlags = usesPermissionFlags; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { sForInternedString.parcel(this.name, dest, flags); dest.writeInt(usesPermissionFlags); } @Override public int describeContents() { return 0; } protected ParsedUsesPermission(@NonNull Parcel in) { this.name = sForInternedString.unparcel(in); this.usesPermissionFlags = in.readInt(); } public static final @NonNull Parcelable.Creator<ParsedUsesPermission> CREATOR = new Parcelable.Creator<ParsedUsesPermission>() { @Override public ParsedUsesPermission[] newArray(int size) { return new ParsedUsesPermission[size]; } @Override public ParsedUsesPermission createFromParcel(@NonNull Parcel in) { return new ParsedUsesPermission(in); } }; }