Loading core/java/android/permission/PermissionManager.java +15 −27 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } Loading core/java/com/android/server/SystemConfig.java +51 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -192,6 +195,10 @@ public class SystemConfig { return mSystemPermissions; } public ArrayList<SplitPermissionInfo> getSplitPermissions() { return mSplitPermissions; } public ArrayMap<String, String> getSharedLibraries() { return mSharedLibraries; } Loading Loading @@ -484,6 +491,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"); Loading Loading @@ -883,4 +892,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)); } } } data/etc/platform.xml +20 −0 Original line number Diff line number Diff line Loading @@ -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. --> Loading Loading
core/java/android/permission/PermissionManager.java +15 −27 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } Loading
core/java/com/android/server/SystemConfig.java +51 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -192,6 +195,10 @@ public class SystemConfig { return mSystemPermissions; } public ArrayList<SplitPermissionInfo> getSplitPermissions() { return mSplitPermissions; } public ArrayMap<String, String> getSharedLibraries() { return mSharedLibraries; } Loading Loading @@ -484,6 +491,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"); Loading Loading @@ -883,4 +892,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)); } } }
data/etc/platform.xml +20 −0 Original line number Diff line number Diff line Loading @@ -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. --> Loading