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

Commit 3ea5ce64 authored by Michael Groover's avatar Michael Groover Committed by Automerger Merge Worker
Browse files

Merge "Include knownCerts in Parcels for PermissionInfo and ParsedPermission"...

Merge "Include knownCerts in Parcels for PermissionInfo and ParsedPermission" into sc-dev am: 87d49d2f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13551675

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Id9a7843d50ad62c6e10ea7abfe7b5702874e96d1
parents d4b86dbf 87d49d2f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import com.android.internal.util.Parcelling;
import com.android.internal.util.Parcelling.BuiltIn.ForStringSet;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Set;
@@ -477,6 +480,8 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
     */
    public @Nullable CharSequence nonLocalizedDescription;

    private static ForStringSet sForStringSet = Parcelling.Cache.getOrCreate(ForStringSet.class);

    /**
     * A {@link Set} of trusted signing certificate digests. If this permission has the {@link
     * #PROTECTION_FLAG_KNOWN_SIGNER} flag set the permission will be granted to a requesting app
@@ -688,6 +693,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
        dest.writeInt(descriptionRes);
        dest.writeInt(requestRes);
        TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags);
        sForStringSet.parcel(knownCerts, dest, parcelableFlags);
    }

    /** @hide */
@@ -753,5 +759,6 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
        descriptionRes = source.readInt();
        requestRes = source.readInt();
        nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
        knownCerts = sForStringSet.unparcel(source);
    }
}
+21 −0
Original line number Diff line number Diff line
@@ -21,16 +21,22 @@ 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 ParsedComponent {

    private static ForStringSet sForStringSet = Parcelling.Cache.getOrCreate(ForStringSet.class);

    @Nullable
    String backgroundPermission;
    @Nullable
@@ -89,6 +95,19 @@ public class ParsedPermission extends ParsedComponent {
        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) {
@@ -117,6 +136,7 @@ public class ParsedPermission extends ParsedComponent {
        dest.writeInt(this.protectionLevel);
        dest.writeBoolean(this.tree);
        dest.writeParcelable(this.parsedPermissionGroup, flags);
        sForStringSet.parcel(knownCerts, dest, flags);
    }

    protected ParsedPermission(Parcel in) {
@@ -129,6 +149,7 @@ public class ParsedPermission extends ParsedComponent {
        this.protectionLevel = in.readInt();
        this.tree = in.readBoolean();
        this.parsedPermissionGroup = in.readParcelable(boot);
        this.knownCerts = sForStringSet.unparcel(in);
    }

    public static final Parcelable.Creator<ParsedPermission> CREATOR =
+3 −11
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.content.pm.parsing.result.ParseResult;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.util.ArraySet;
import android.util.Slog;

import com.android.internal.R;
@@ -33,8 +32,6 @@ import com.android.internal.R;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.Locale;
import java.util.Set;

/** @hide */
public class ParsedPermissionUtils {
@@ -103,17 +100,12 @@ public class ParsedPermissionUtils {
                if (resourceType.equals("array")) {
                    final String[] knownCerts = res.getStringArray(knownCertsResource);
                    if (knownCerts != null) {
                        // Convert the provided digest to upper case for consistent Set membership
                        // checks when verifying the signing certificate digests of requesting apps.
                        permission.knownCerts = new ArraySet<>();
                        for (String knownCert : knownCerts) {
                            permission.knownCerts.add(knownCert.toUpperCase(Locale.US));
                        }
                        permission.setKnownCerts(knownCerts);
                    }
                } else {
                    final String knownCert = res.getString(knownCertsResource);
                    if (knownCert != null) {
                        permission.knownCerts = Set.of(knownCert.toUpperCase(Locale.US));
                        permission.setKnownCert(knownCert);
                    }
                }
                if (permission.knownCerts == null) {
@@ -126,7 +118,7 @@ public class ParsedPermissionUtils {
                final String knownCert = sa.getString(
                        R.styleable.AndroidManifestPermission_knownCerts);
                if (knownCert != null) {
                    permission.knownCerts = Set.of(knownCert.toUpperCase(Locale.US));
                    permission.setKnownCert(knownCert);
                }
            }

+61 −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;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import android.os.Parcel;
import android.util.ArraySet;

import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
public final class PermissionInfoTest {
    private static final String KNOWN_CERT_DIGEST_1 =
            "6a8b96e278e58f62cfe3584022cec1d0527fcb85a9e5d2e1694eb0405be5b599";
    private static final String KNOWN_CERT_DIGEST_2 =
            "9369370ffcfdc1e92dae777252c05c483b8cbb55fa9d5fd9f6317f623ae6d8c6";

    @Test
    public void createFromParcel_returnsKnownCerts() {
        // The platform supports a knownSigner permission protection flag that allows one or more
        // trusted signing certificates to be specified with the permission declaration; if a
        // requesting app is signed by any of these trusted certificates the permission is granted.
        // This test verifies the Set of knownCerts is properly parceled / unparceled.
        PermissionInfo permissionInfo = new PermissionInfo();
        permissionInfo.protectionLevel =
                PermissionInfo.PROTECTION_SIGNATURE | PermissionInfo.PROTECTION_FLAG_KNOWN_SIGNER;
        permissionInfo.knownCerts = new ArraySet<>(2);
        permissionInfo.knownCerts.add(KNOWN_CERT_DIGEST_1);
        permissionInfo.knownCerts.add(KNOWN_CERT_DIGEST_2);
        Parcel parcel = Parcel.obtain();
        permissionInfo.writeToParcel(parcel, 0);

        parcel.setDataPosition(0);
        PermissionInfo unparceledPermissionInfo = PermissionInfo.CREATOR.createFromParcel(parcel);

        assertNotNull(unparceledPermissionInfo.knownCerts);
        assertEquals(2, unparceledPermissionInfo.knownCerts.size());
        assertTrue(unparceledPermissionInfo.knownCerts.contains(KNOWN_CERT_DIGEST_1));
        assertTrue(unparceledPermissionInfo.knownCerts.contains(KNOWN_CERT_DIGEST_2));
    }
}