Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8a9a21a authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Add flags to <uses-permission> manifest tags." into sc-dev

parents 065b6513 ea48e8e8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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);

+20 −7
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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();
@@ -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;
    }

@@ -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);
@@ -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);
@@ -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() {
+11 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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
@@ -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
+31 −8
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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
@@ -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();
@@ -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);
            }
        }
@@ -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);
                }
            }
+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
 * &lt;uses-permission&gt;} 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