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

Commit cc2932fd authored by Zimuzo's avatar Zimuzo
Browse files

Grant split permission from config

Instead of defining split permissions in Java file, we now move them to XML allowing us define vendor specific split permissions.

Test: Activity recognition is split correctly and auto granted when below split targetSdk.
Bug: 111411340
Change-Id: Ia5b3f47b73c9feea924373268a4eee142f555091
parent f7517f15
Loading
Loading
Loading
Loading
+15 −27
Original line number Diff line number Diff line
@@ -16,16 +16,15 @@

package android.permission;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;

import com.android.internal.annotations.Immutable;
import com.android.server.SystemConfig;

import java.util.Arrays;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@@ -42,28 +41,8 @@ public final class PermissionManager {
     *
     * @hide
     */
    public static final List<SplitPermissionInfo> SPLIT_PERMISSIONS = Arrays.asList(
            // READ_EXTERNAL_STORAGE is always required when an app requests
            // WRITE_EXTERNAL_STORAGE, because we can't have an app that has
            // write access without read access.  The hack here with the target
            // target SDK version ensures that this grant is always done.
            new SplitPermissionInfo(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Collections.singletonList(android.Manifest.permission.READ_EXTERNAL_STORAGE),
                    android.os.Build.VERSION_CODES.CUR_DEVELOPMENT + 1),
            new SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS,
                    Collections.singletonList(android.Manifest.permission.READ_CALL_LOG),
                    android.os.Build.VERSION_CODES.JELLY_BEAN),
            new SplitPermissionInfo(android.Manifest.permission.WRITE_CONTACTS,
                    Collections.singletonList(android.Manifest.permission.WRITE_CALL_LOG),
                    android.os.Build.VERSION_CODES.JELLY_BEAN),
            new SplitPermissionInfo(Manifest.permission.ACCESS_FINE_LOCATION,
                    Collections.singletonList(
                            android.Manifest.permission.ACCESS_BACKGROUND_LOCATION),
                    android.os.Build.VERSION_CODES.P0),
            new SplitPermissionInfo(Manifest.permission.ACCESS_COARSE_LOCATION,
                    Collections.singletonList(
                            android.Manifest.permission.ACCESS_BACKGROUND_LOCATION),
                    android.os.Build.VERSION_CODES.P0));
    public static final ArrayList<SplitPermissionInfo> SPLIT_PERMISSIONS =
            SystemConfig.getInstance().getSplitPermissions();

    private final @NonNull Context mContext;

@@ -145,9 +124,18 @@ public final class PermissionManager {
            return mTargetSdk;
        }

        private SplitPermissionInfo(@NonNull String rootPerm, @NonNull List<String> newPerms,
        /**
         * Constructs a split permission.
         *
         * @param splitPerm old permission that will be split
         * @param newPerms list of new permissions that {@code rootPerm} will be split into
         * @param targetSdk apps targetting SDK versions below this will have {@code rootPerm}
         * split into {@code newPerms}
         * @hide
         */
        public SplitPermissionInfo(@NonNull String splitPerm, @NonNull List<String> newPerms,
                int targetSdk) {
            mSplitPerm = rootPerm;
            mSplitPerm = splitPerm;
            mNewPerms = newPerms;
            mTargetSdk = targetSdk;
        }
+51 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.Build;
import android.os.Environment;
import android.os.Process;
import android.os.storage.StorageManager;
import android.permission.PermissionManager.SplitPermissionInfo;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -74,6 +75,8 @@ public class SystemConfig {
    // system configuration files.
    final SparseArray<ArraySet<String>> mSystemPermissions = new SparseArray<>();

    final ArrayList<SplitPermissionInfo> mSplitPermissions = new ArrayList<>();

    // These are the built-in shared libraries that were read from the
    // system configuration files.  Keys are the library names; strings are the
    // paths to the libraries.
@@ -192,6 +195,10 @@ public class SystemConfig {
        return mSystemPermissions;
    }

    public ArrayList<SplitPermissionInfo> getSplitPermissions() {
        return mSplitPermissions;
    }

    public ArrayMap<String, String> getSharedLibraries() {
        return mSharedLibraries;
    }
@@ -489,6 +496,8 @@ public class SystemConfig {
                    perms.add(perm);
                    XmlUtils.skipCurrentTag(parser);

                } else if ("split-permission".equals(name) && allowPermissions) {
                    readSplitPermission(parser, permFile);
                } else if ("library".equals(name) && allowLibs) {
                    String lname = parser.getAttributeValue(null, "name");
                    String lfile = parser.getAttributeValue(null, "file");
@@ -888,4 +897,46 @@ public class SystemConfig {
        }
        mOemPermissions.put(packageName, permissions);
    }

    private void readSplitPermission(XmlPullParser parser, File permFile)
            throws IOException, XmlPullParserException {
        String splitPerm = parser.getAttributeValue(null, "name");
        if (splitPerm == null) {
            Slog.w(TAG, "<split-permission> without name in " + permFile + " at "
                    + parser.getPositionDescription());
            XmlUtils.skipCurrentTag(parser);
            return;
        }
        String targetSdkStr = parser.getAttributeValue(null, "targetSdk");
        int targetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT + 1;
        if (!TextUtils.isEmpty(targetSdkStr)) {
            try {
                targetSdk = Integer.parseInt(targetSdkStr);
            } catch (NumberFormatException e) {
                Slog.w(TAG, "<split-permission> targetSdk not an integer in " + permFile + " at "
                        + parser.getPositionDescription());
                XmlUtils.skipCurrentTag(parser);
                return;
            }
        }
        final int depth = parser.getDepth();
        List<String> newPermissions = new ArrayList<>();
        while (XmlUtils.nextElementWithin(parser, depth)) {
            String name = parser.getName();
            if ("new-permission".equals(name)) {
                final String newName = parser.getAttributeValue(null, "name");
                if (TextUtils.isEmpty(newName)) {
                    Slog.w(TAG, "name is required for <new-permission> in "
                            + parser.getPositionDescription());
                    continue;
                }
                newPermissions.add(newName);
            } else {
                XmlUtils.skipCurrentTag(parser);
            }
        }
        if (!newPermissions.isEmpty()) {
            mSplitPermissions.add(new SplitPermissionInfo(splitPerm, newPermissions, targetSdk));
        }
    }
}
+20 −0
Original line number Diff line number Diff line
@@ -178,6 +178,26 @@
    <assign-permission name="android.permission.STATSCOMPANION" uid="statsd" />
    <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="statsd" />

    <split-permission name="android.permission.WRITE_EXTERNAL_STORAGE">
        <new-permission name="android.permission.READ_EXTERNAL_STORAGE" />
    </split-permission>
    <split-permission name="android.permission.READ_CONTACTS"
                      targetSdk="16">
        <new-permission name="android.permission.READ_CALL_LOG" />
    </split-permission>
    <split-permission name="android.permission.WRITE_CONTACTS"
                      targetSdk="16">
        <new-permission name="android.permission.WRITE_CALL_LOG" />
    </split-permission>
    <split-permission name="android.permission.ACCESS_FINE_LOCATION"
                      targetSdk="28">
        <new-permission name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    </split-permission>
    <split-permission name="android.permission.ACCESS_COARSE_LOCATION"
                      targetSdk="28">
        <new-permission name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    </split-permission>

    <!-- This is a list of all the libraries available for application
         code to link against. -->