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

Commit 594ea5f8 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Implement issue #34842682: Add ability to limit permissions based on features"

parents 77f53170 cd154e95
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -1005,7 +1005,7 @@ package android {
    field public static final int preferenceStyle = 16842894; // 0x101008e
    field public static final int presentationTheme = 16843712; // 0x10103c0
    field public static final int previewImage = 16843482; // 0x10102da
    field public static final int primaryContentAlpha = 16843367; // 0x1010267
    field public static final int primaryContentAlpha = 16844117; // 0x1010555
    field public static final int priority = 16842780; // 0x101001c
    field public static final int privateImeOptions = 16843299; // 0x1010223
    field public static final int process = 16842769; // 0x1010011
@@ -1061,7 +1061,9 @@ package android {
    field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
    field public static final int required = 16843406; // 0x101028e
    field public static final int requiredAccountType = 16843734; // 0x10103d6
    field public static final int requiredFeature = 16844119; // 0x1010557
    field public static final int requiredForAllUsers = 16843728; // 0x10103d0
    field public static final int requiredNotFeature = 16844120; // 0x1010558
    field public static final int requiresFadingEdge = 16843685; // 0x10103a5
    field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
    field public static final int resizeClip = 16843983; // 0x10104cf
@@ -1130,7 +1132,7 @@ package android {
    field public static final int searchSuggestSelection = 16843224; // 0x10101d8
    field public static final int searchSuggestThreshold = 16843373; // 0x101026d
    field public static final int searchViewStyle = 16843904; // 0x1010480
    field public static final int secondaryContentAlpha = 16843688; // 0x10103a8
    field public static final int secondaryContentAlpha = 16844118; // 0x1010556
    field public static final int secondaryProgress = 16843064; // 0x1010138
    field public static final int secondaryProgressTint = 16843879; // 0x1010467
    field public static final int secondaryProgressTintMode = 16843880; // 0x1010468
+4 −2
Original line number Diff line number Diff line
@@ -1117,7 +1117,7 @@ package android {
    field public static final int preferenceStyle = 16842894; // 0x101008e
    field public static final int presentationTheme = 16843712; // 0x10103c0
    field public static final int previewImage = 16843482; // 0x10102da
    field public static final int primaryContentAlpha = 16843367; // 0x1010267
    field public static final int primaryContentAlpha = 16844117; // 0x1010555
    field public static final int priority = 16842780; // 0x101001c
    field public static final int privateImeOptions = 16843299; // 0x1010223
    field public static final int process = 16842769; // 0x1010011
@@ -1173,7 +1173,9 @@ package android {
    field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
    field public static final int required = 16843406; // 0x101028e
    field public static final int requiredAccountType = 16843734; // 0x10103d6
    field public static final int requiredFeature = 16844119; // 0x1010557
    field public static final int requiredForAllUsers = 16843728; // 0x10103d0
    field public static final int requiredNotFeature = 16844120; // 0x1010558
    field public static final int requiresFadingEdge = 16843685; // 0x10103a5
    field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
    field public static final int resizeClip = 16843983; // 0x10104cf
@@ -1246,7 +1248,7 @@ package android {
    field public static final int searchSuggestSelection = 16843224; // 0x10101d8
    field public static final int searchSuggestThreshold = 16843373; // 0x101026d
    field public static final int searchViewStyle = 16843904; // 0x1010480
    field public static final int secondaryContentAlpha = 16843688; // 0x10103a8
    field public static final int secondaryContentAlpha = 16844118; // 0x1010556
    field public static final int secondaryProgress = 16843064; // 0x1010138
    field public static final int secondaryProgressTint = 16843879; // 0x1010467
    field public static final int secondaryProgressTintMode = 16843880; // 0x1010468
+4 −2
Original line number Diff line number Diff line
@@ -1005,7 +1005,7 @@ package android {
    field public static final int preferenceStyle = 16842894; // 0x101008e
    field public static final int presentationTheme = 16843712; // 0x10103c0
    field public static final int previewImage = 16843482; // 0x10102da
    field public static final int primaryContentAlpha = 16843367; // 0x1010267
    field public static final int primaryContentAlpha = 16844117; // 0x1010555
    field public static final int priority = 16842780; // 0x101001c
    field public static final int privateImeOptions = 16843299; // 0x1010223
    field public static final int process = 16842769; // 0x1010011
@@ -1061,7 +1061,9 @@ package android {
    field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
    field public static final int required = 16843406; // 0x101028e
    field public static final int requiredAccountType = 16843734; // 0x10103d6
    field public static final int requiredFeature = 16844119; // 0x1010557
    field public static final int requiredForAllUsers = 16843728; // 0x10103d0
    field public static final int requiredNotFeature = 16844120; // 0x1010558
    field public static final int requiresFadingEdge = 16843685; // 0x10103a5
    field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
    field public static final int resizeClip = 16843983; // 0x10104cf
@@ -1130,7 +1132,7 @@ package android {
    field public static final int searchSuggestSelection = 16843224; // 0x10101d8
    field public static final int searchSuggestThreshold = 16843373; // 0x101026d
    field public static final int searchViewStyle = 16843904; // 0x1010480
    field public static final int secondaryContentAlpha = 16843688; // 0x10103a8
    field public static final int secondaryContentAlpha = 16844118; // 0x1010556
    field public static final int secondaryProgress = 16843064; // 0x1010138
    field public static final int secondaryProgressTint = 16843879; // 0x1010467
    field public static final int secondaryProgressTintMode = 16843880; // 0x1010468
+1 −0
Original line number Diff line number Diff line
@@ -5000,6 +5000,7 @@ public abstract class PackageManager {
     */
    public PackageInfo getPackageArchiveInfo(String archiveFilePath, @PackageInfoFlags int flags) {
        final PackageParser parser = new PackageParser();
        parser.setCallback(new PackageParser.CallbackImpl(this));
        final File apkFile = new File(archiveFilePath);
        try {
            if ((flags & (MATCH_DIRECT_BOOT_UNAWARE | MATCH_DIRECT_BOOT_AWARE)) != 0) {
+85 −31
Original line number Diff line number Diff line
@@ -285,6 +285,7 @@ public class PackageParser {
    private String[] mSeparateProcesses;
    private boolean mOnlyCoreApps;
    private DisplayMetrics mMetrics;
    private Callback mCallback;
    private File mCacheDir;

    private static final int SDK_VERSION = Build.VERSION.SDK_INT;
@@ -506,6 +507,37 @@ public class PackageParser {
        mCacheDir = cacheDir;
    }

    /**
     * Callback interface for retrieving information that may be needed while parsing
     * a package.
     */
    public interface Callback {
        boolean hasFeature(String feature);
    }

    /**
     * Standard implementation of {@link Callback} on top of the public {@link PackageManager}
     * class.
     */
    public static final class CallbackImpl implements Callback {
        private final PackageManager mPm;

        public CallbackImpl(PackageManager pm) {
            mPm = pm;
        }

        @Override public boolean hasFeature(String feature) {
            return mPm.hasSystemFeature(feature);
        }
    }

    /**
     * Set the {@link Callback} that can be used while parsing.
     */
    public void setCallback(Callback cb) {
        mCallback = cb;
    }

    public static final boolean isApkFile(File file) {
        return isApkPath(file.getName());
    }
@@ -2079,15 +2111,15 @@ public class PackageParser {
                    return null;
                }
            } else if (tagName.equals(TAG_PERMISSION_GROUP)) {
                if (parsePermissionGroup(pkg, flags, res, parser, outError) == null) {
                if (!parsePermissionGroup(pkg, flags, res, parser, outError)) {
                    return null;
                }
            } else if (tagName.equals(TAG_PERMISSION)) {
                if (parsePermission(pkg, res, parser, outError) == null) {
                if (!parsePermission(pkg, res, parser, outError)) {
                    return null;
                }
            } else if (tagName.equals(TAG_PERMISSION_TREE)) {
                if (parsePermissionTree(pkg, res, parser, outError) == null) {
                if (!parsePermissionTree(pkg, res, parser, outError)) {
                    return null;
                }
            } else if (tagName.equals(TAG_USES_PERMISSION)) {
@@ -2708,10 +2740,35 @@ public class PackageParser {
            }
        }

        final String requiredFeature = sa.getNonConfigurationString(
                com.android.internal.R.styleable.AndroidManifestUsesPermission_requiredFeature, 0);

        final String requiredNotfeature = sa.getNonConfigurationString(
                com.android.internal.R.styleable.AndroidManifestUsesPermission_requiredNotFeature, 0);

        sa.recycle();

        if ((maxSdkVersion == 0) || (maxSdkVersion >= Build.VERSION.RESOURCES_SDK_INT)) {
            if (name != null) {
        XmlUtils.skipCurrentTag(parser);

        if (name == null) {
            return true;
        }

        if ((maxSdkVersion != 0) && (maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT)) {
            return true;
        }

        // Only allow requesting this permission if the platform supports the given feature.
        if (requiredFeature != null && mCallback != null && !mCallback.hasFeature(requiredFeature)) {
            return true;
        }

        // Only allow requesting this permission if the platform doesn't support the given feature.
        if (requiredNotfeature != null && mCallback != null
                && mCallback.hasFeature(requiredNotfeature)) {
            return true;
        }

        int index = pkg.requestedPermissions.indexOf(name);
        if (index == -1) {
            pkg.requestedPermissions.add(name.intern());
@@ -2720,10 +2777,7 @@ public class PackageParser {
                    + name + " in package: " + pkg.packageName + " at: "
                    + parser.getPositionDescription());
        }
            }
        }

        XmlUtils.skipCurrentTag(parser);
        return true;
    }

@@ -2951,7 +3005,7 @@ public class PackageParser {
        return true;
    }

    private PermissionGroup parsePermissionGroup(Package owner, int flags, Resources res,
    private boolean parsePermissionGroup(Package owner, int flags, Resources res,
            XmlResourceParser parser, String[] outError)
            throws XmlPullParserException, IOException {
        PermissionGroup perm = new PermissionGroup(owner);
@@ -2968,7 +3022,7 @@ public class PackageParser {
                com.android.internal.R.styleable.AndroidManifestPermissionGroup_banner)) {
            sa.recycle();
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return null;
            return false;
        }

        perm.info.descriptionRes = sa.getResourceId(
@@ -2987,22 +3041,22 @@ public class PackageParser {
        if (!parseAllMetaData(res, parser, "<permission-group>", perm,
                outError)) {
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return null;
            return false;
        }

        owner.permissionGroups.add(perm);

        return perm;
        return true;
    }

    private Permission parsePermission(Package owner, Resources res,
    private boolean parsePermission(Package owner, Resources res,
            XmlResourceParser parser, String[] outError)
        throws XmlPullParserException, IOException {
        Permission perm = new Permission(owner);

        TypedArray sa = res.obtainAttributes(parser,
                com.android.internal.R.styleable.AndroidManifestPermission);

        Permission perm = new Permission(owner);
        if (!parsePackageItemInfo(owner, perm.info, outError,
                "<permission>", sa, true /*nameRequired*/,
                com.android.internal.R.styleable.AndroidManifestPermission_name,
@@ -3013,7 +3067,7 @@ public class PackageParser {
                com.android.internal.R.styleable.AndroidManifestPermission_banner)) {
            sa.recycle();
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return null;
            return false;
        }

        // Note: don't allow this value to be a reference to a resource
@@ -3040,7 +3094,7 @@ public class PackageParser {
        if (perm.info.protectionLevel == -1) {
            outError[0] = "<permission> does not specify protectionLevel";
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return null;
            return false;
        }

        perm.info.protectionLevel = PermissionInfo.fixProtectionLevel(perm.info.protectionLevel);
@@ -3052,21 +3106,21 @@ public class PackageParser {
                outError[0] = "<permission>  protectionLevel specifies a non-ephemeral flag but is "
                        + "not based on signature type";
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return null;
                return false;
            }
        }

        if (!parseAllMetaData(res, parser, "<permission>", perm, outError)) {
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return null;
            return false;
        }

        owner.permissions.add(perm);

        return perm;
        return true;
    }

    private Permission parsePermissionTree(Package owner, Resources res,
    private boolean parsePermissionTree(Package owner, Resources res,
            XmlResourceParser parser, String[] outError)
        throws XmlPullParserException, IOException {
        Permission perm = new Permission(owner);
@@ -3084,7 +3138,7 @@ public class PackageParser {
                com.android.internal.R.styleable.AndroidManifestPermissionTree_banner)) {
            sa.recycle();
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return null;
            return false;
        }

        sa.recycle();
@@ -3097,7 +3151,7 @@ public class PackageParser {
            outError[0] = "<permission-tree> name has less than three segments: "
                + perm.info.name;
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return null;
            return false;
        }

        perm.info.descriptionRes = 0;
@@ -3107,12 +3161,12 @@ public class PackageParser {
        if (!parseAllMetaData(res, parser, "<permission-tree>", perm,
                outError)) {
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return null;
            return false;
        }

        owner.permissions.add(perm);

        return perm;
        return true;
    }

    private Instrumentation parseInstrumentation(Package owner, Resources res,
Loading