Loading api/system-current.txt +15 −0 Original line number Diff line number Diff line Loading @@ -950,6 +950,7 @@ package android.content { field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control"; field public static final java.lang.String NETWORK_SCORE_SERVICE = "network_score"; field public static final java.lang.String OEM_LOCK_SERVICE = "oem_lock"; field public static final java.lang.String PERMISSION_SERVICE = "permission"; field public static final java.lang.String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block"; field public static final java.lang.String SECURE_ELEMENT_SERVICE = "secure_element"; field public static final java.lang.String STATS_MANAGER = "stats"; Loading Loading @@ -4192,6 +4193,20 @@ package android.os.storage { } package android.permission { public final class PermissionManager { method public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions(); } public static final class PermissionManager.SplitPermissionInfo { method public java.lang.String[] getNewPermissions(); method public java.lang.String getRootPermission(); method public int getTargetSdk(); } } package android.permissionpresenterservice { public abstract class RuntimePermissionPresenterService extends android.app.Service { Loading core/java/android/app/SystemServiceRegistry.java +8 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ import android.os.UserManager; import android.os.Vibrator; import android.os.health.SystemHealthManager; import android.os.storage.StorageManager; import android.permission.PermissionManager; import android.print.IPrintManager; import android.print.PrintManager; import android.service.oemlock.IOemLockService; Loading Loading @@ -1064,6 +1065,13 @@ final class SystemServiceRegistry { throws ServiceNotFoundException { return new TimeZoneDetector(); }}); registerService(Context.PERMISSION_SERVICE, PermissionManager.class, new CachedServiceFetcher<PermissionManager>() { @Override public PermissionManager createService(ContextImpl ctx) { return new PermissionManager(ctx.getOuterContext()); }}); } /** Loading core/java/android/content/Context.java +9 −0 Original line number Diff line number Diff line Loading @@ -3088,6 +3088,7 @@ public abstract class Context { //@hide: SYSTEM_UPDATE_SERVICE, //@hide: TIME_DETECTOR_SERVICE, //@hide: TIME_ZONE_DETECTOR_SERVICE, PERMISSION_SERVICE, }) @Retention(RetentionPolicy.SOURCE) public @interface ServiceName {} Loading Loading @@ -3860,6 +3861,14 @@ public abstract class Context { */ public static final String SOUND_TRIGGER_SERVICE = "soundtrigger"; /** * Official published name of the (internal) permission service. * * @see #getSystemService(String) * @hide */ @SystemApi public static final String PERMISSION_SERVICE = "permission"; /** * Use with {@link #getSystemService(String)} to retrieve an Loading core/java/android/content/pm/PackageParser.java +10 −49 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ import static android.os.Build.VERSION_CODES.O; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED; import android.Manifest; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; Loading Loading @@ -73,6 +72,7 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.os.storage.StorageManager; import android.permission.PermissionManager; import android.system.ErrnoException; import android.system.OsConstants; import android.system.StructStat; Loading Loading @@ -258,19 +258,6 @@ public class PackageParser { } } /** @hide */ public static class SplitPermissionInfo { public final String rootPerm; public final String[] newPerms; public final int targetSdk; public SplitPermissionInfo(String rootPerm, String[] newPerms, int targetSdk) { this.rootPerm = rootPerm; this.newPerms = newPerms; this.targetSdk = targetSdk; } } /** * List of new permissions that have been added since 1.0. * NOTE: These must be declared in SDK version order, with permissions Loading @@ -289,34 +276,6 @@ public class PackageParser { android.os.Build.VERSION_CODES.DONUT, 0) }; /** * List of permissions that have been split into more granular or dependent * permissions. * @hide */ public static final PackageParser.SplitPermissionInfo SPLIT_PERMISSIONS[] = new PackageParser.SplitPermissionInfo[] { // 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 PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, new String[] { android.Manifest.permission.READ_EXTERNAL_STORAGE }, android.os.Build.VERSION_CODES.CUR_DEVELOPMENT+1), new PackageParser.SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS, new String[] { android.Manifest.permission.READ_CALL_LOG }, android.os.Build.VERSION_CODES.JELLY_BEAN), new PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_CONTACTS, new String[] { android.Manifest.permission.WRITE_CALL_LOG }, android.os.Build.VERSION_CODES.JELLY_BEAN), new PackageParser.SplitPermissionInfo(Manifest.permission.ACCESS_FINE_LOCATION, new String[] { android.Manifest.permission.ACCESS_BACKGROUND_LOCATION }, android.os.Build.VERSION_CODES.P0), new PackageParser.SplitPermissionInfo(Manifest.permission.ACCESS_COARSE_LOCATION, new String[] { android.Manifest.permission.ACCESS_BACKGROUND_LOCATION }, android.os.Build.VERSION_CODES.P0), }; /** * @deprecated callers should move to explicitly passing around source path. */ Loading Loading @@ -2474,16 +2433,18 @@ public class PackageParser { Slog.i(TAG, implicitPerms.toString()); } final int NS = PackageParser.SPLIT_PERMISSIONS.length; final int NS = PermissionManager.SPLIT_PERMISSIONS.length; for (int is=0; is<NS; is++) { final PackageParser.SplitPermissionInfo spi = PackageParser.SPLIT_PERMISSIONS[is]; if (pkg.applicationInfo.targetSdkVersion >= spi.targetSdk || !pkg.requestedPermissions.contains(spi.rootPerm)) { final PermissionManager.SplitPermissionInfo spi = PermissionManager.SPLIT_PERMISSIONS[is]; if (pkg.applicationInfo.targetSdkVersion >= spi.getTargetSdk() || !pkg.requestedPermissions.contains(spi.getRootPermission())) { continue; } for (int in=0; in<spi.newPerms.length; in++) { final String perm = spi.newPerms[in]; final String[] newPerms = spi.getNewPermissions(); for (int in = 0; in < newPerms.length; in++) { final String perm = newPerms[in]; if (!pkg.requestedPermissions.contains(perm)) { pkg.requestedPermissions.add(perm); } Loading core/java/android/permission/PermissionManager.java 0 → 100644 +136 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.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 java.util.Arrays; import java.util.List; /** * System level service for accessing the permission capabilities of the platform. * * @hide */ @SystemApi @SystemService(Context.PERMISSION_SERVICE) public final class PermissionManager { /** * {@link android.content.pm.PackageParser} needs access without having a {@link Context}. * * @hide */ public static final SplitPermissionInfo[] SPLIT_PERMISSIONS = new SplitPermissionInfo[]{ // 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, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, android.os.Build.VERSION_CODES.CUR_DEVELOPMENT + 1), new SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS, new String[]{android.Manifest.permission.READ_CALL_LOG}, android.os.Build.VERSION_CODES.JELLY_BEAN), new SplitPermissionInfo(android.Manifest.permission.WRITE_CONTACTS, new String[]{android.Manifest.permission.WRITE_CALL_LOG}, android.os.Build.VERSION_CODES.JELLY_BEAN), new SplitPermissionInfo(Manifest.permission.ACCESS_FINE_LOCATION, new String[]{android.Manifest.permission.ACCESS_BACKGROUND_LOCATION}, android.os.Build.VERSION_CODES.P0), new SplitPermissionInfo(Manifest.permission.ACCESS_COARSE_LOCATION, new String[]{android.Manifest.permission.ACCESS_BACKGROUND_LOCATION}, android.os.Build.VERSION_CODES.P0)}; private final @NonNull Context mContext; /** * Creates a new instance. * * @param context The current context in which to operate. * @hide */ public PermissionManager(@NonNull Context context) { mContext = context; } /** * Get list of permissions that have been split into more granular or dependent permissions. * * <p>E.g. before {@link android.os.Build.VERSION_CODES#P0} an app that was granted * {@link Manifest.permission#ACCESS_COARSE_LOCATION} could access he location while it was in * foreground and background. On platforms after {@link android.os.Build.VERSION_CODES#P0} * the location permission only grants location access while the app is in foreground. This * would break apps that target before {@link android.os.Build.VERSION_CODES#P0}. Hence whenever * such an old app asks for a location permission (i.e. the * {@link SplitPermissionInfo#getRootPermission()}), then the * {@link Manifest.permission#ACCESS_BACKGROUND_LOCATION} permission (inside * {@{@link SplitPermissionInfo#getNewPermissions}) is added. * * <p>Note: Regular apps do not have to worry about this. The platform and permission controller * automatically add the new permissions where needed. * * @return All permissions that are split. */ public @NonNull List<SplitPermissionInfo> getSplitPermissions() { return Arrays.asList(SPLIT_PERMISSIONS); } /** * A permission that was added in a previous API level might have split into several * permissions. This object describes one such split. */ @Immutable public static final class SplitPermissionInfo { private final @NonNull String mRootPerm; private final @NonNull String[] mNewPerms; private final int mTargetSdk; /** * Get the permission that is split. */ public @NonNull String getRootPermission() { return mRootPerm; } /** * Get the permissions that are added. */ public @NonNull String[] getNewPermissions() { return mNewPerms; } /** * Get the target API level when the permission was split. */ public int getTargetSdk() { return mTargetSdk; } private SplitPermissionInfo(@NonNull String rootPerm, @NonNull String[] newPerms, int targetSdk) { mRootPerm = rootPerm; mNewPerms = newPerms; mTargetSdk = targetSdk; } } } Loading
api/system-current.txt +15 −0 Original line number Diff line number Diff line Loading @@ -950,6 +950,7 @@ package android.content { field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control"; field public static final java.lang.String NETWORK_SCORE_SERVICE = "network_score"; field public static final java.lang.String OEM_LOCK_SERVICE = "oem_lock"; field public static final java.lang.String PERMISSION_SERVICE = "permission"; field public static final java.lang.String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block"; field public static final java.lang.String SECURE_ELEMENT_SERVICE = "secure_element"; field public static final java.lang.String STATS_MANAGER = "stats"; Loading Loading @@ -4192,6 +4193,20 @@ package android.os.storage { } package android.permission { public final class PermissionManager { method public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions(); } public static final class PermissionManager.SplitPermissionInfo { method public java.lang.String[] getNewPermissions(); method public java.lang.String getRootPermission(); method public int getTargetSdk(); } } package android.permissionpresenterservice { public abstract class RuntimePermissionPresenterService extends android.app.Service { Loading
core/java/android/app/SystemServiceRegistry.java +8 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ import android.os.UserManager; import android.os.Vibrator; import android.os.health.SystemHealthManager; import android.os.storage.StorageManager; import android.permission.PermissionManager; import android.print.IPrintManager; import android.print.PrintManager; import android.service.oemlock.IOemLockService; Loading Loading @@ -1064,6 +1065,13 @@ final class SystemServiceRegistry { throws ServiceNotFoundException { return new TimeZoneDetector(); }}); registerService(Context.PERMISSION_SERVICE, PermissionManager.class, new CachedServiceFetcher<PermissionManager>() { @Override public PermissionManager createService(ContextImpl ctx) { return new PermissionManager(ctx.getOuterContext()); }}); } /** Loading
core/java/android/content/Context.java +9 −0 Original line number Diff line number Diff line Loading @@ -3088,6 +3088,7 @@ public abstract class Context { //@hide: SYSTEM_UPDATE_SERVICE, //@hide: TIME_DETECTOR_SERVICE, //@hide: TIME_ZONE_DETECTOR_SERVICE, PERMISSION_SERVICE, }) @Retention(RetentionPolicy.SOURCE) public @interface ServiceName {} Loading Loading @@ -3860,6 +3861,14 @@ public abstract class Context { */ public static final String SOUND_TRIGGER_SERVICE = "soundtrigger"; /** * Official published name of the (internal) permission service. * * @see #getSystemService(String) * @hide */ @SystemApi public static final String PERMISSION_SERVICE = "permission"; /** * Use with {@link #getSystemService(String)} to retrieve an Loading
core/java/android/content/pm/PackageParser.java +10 −49 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ import static android.os.Build.VERSION_CODES.O; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED; import android.Manifest; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; Loading Loading @@ -73,6 +72,7 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.os.storage.StorageManager; import android.permission.PermissionManager; import android.system.ErrnoException; import android.system.OsConstants; import android.system.StructStat; Loading Loading @@ -258,19 +258,6 @@ public class PackageParser { } } /** @hide */ public static class SplitPermissionInfo { public final String rootPerm; public final String[] newPerms; public final int targetSdk; public SplitPermissionInfo(String rootPerm, String[] newPerms, int targetSdk) { this.rootPerm = rootPerm; this.newPerms = newPerms; this.targetSdk = targetSdk; } } /** * List of new permissions that have been added since 1.0. * NOTE: These must be declared in SDK version order, with permissions Loading @@ -289,34 +276,6 @@ public class PackageParser { android.os.Build.VERSION_CODES.DONUT, 0) }; /** * List of permissions that have been split into more granular or dependent * permissions. * @hide */ public static final PackageParser.SplitPermissionInfo SPLIT_PERMISSIONS[] = new PackageParser.SplitPermissionInfo[] { // 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 PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, new String[] { android.Manifest.permission.READ_EXTERNAL_STORAGE }, android.os.Build.VERSION_CODES.CUR_DEVELOPMENT+1), new PackageParser.SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS, new String[] { android.Manifest.permission.READ_CALL_LOG }, android.os.Build.VERSION_CODES.JELLY_BEAN), new PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_CONTACTS, new String[] { android.Manifest.permission.WRITE_CALL_LOG }, android.os.Build.VERSION_CODES.JELLY_BEAN), new PackageParser.SplitPermissionInfo(Manifest.permission.ACCESS_FINE_LOCATION, new String[] { android.Manifest.permission.ACCESS_BACKGROUND_LOCATION }, android.os.Build.VERSION_CODES.P0), new PackageParser.SplitPermissionInfo(Manifest.permission.ACCESS_COARSE_LOCATION, new String[] { android.Manifest.permission.ACCESS_BACKGROUND_LOCATION }, android.os.Build.VERSION_CODES.P0), }; /** * @deprecated callers should move to explicitly passing around source path. */ Loading Loading @@ -2474,16 +2433,18 @@ public class PackageParser { Slog.i(TAG, implicitPerms.toString()); } final int NS = PackageParser.SPLIT_PERMISSIONS.length; final int NS = PermissionManager.SPLIT_PERMISSIONS.length; for (int is=0; is<NS; is++) { final PackageParser.SplitPermissionInfo spi = PackageParser.SPLIT_PERMISSIONS[is]; if (pkg.applicationInfo.targetSdkVersion >= spi.targetSdk || !pkg.requestedPermissions.contains(spi.rootPerm)) { final PermissionManager.SplitPermissionInfo spi = PermissionManager.SPLIT_PERMISSIONS[is]; if (pkg.applicationInfo.targetSdkVersion >= spi.getTargetSdk() || !pkg.requestedPermissions.contains(spi.getRootPermission())) { continue; } for (int in=0; in<spi.newPerms.length; in++) { final String perm = spi.newPerms[in]; final String[] newPerms = spi.getNewPermissions(); for (int in = 0; in < newPerms.length; in++) { final String perm = newPerms[in]; if (!pkg.requestedPermissions.contains(perm)) { pkg.requestedPermissions.add(perm); } Loading
core/java/android/permission/PermissionManager.java 0 → 100644 +136 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.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 java.util.Arrays; import java.util.List; /** * System level service for accessing the permission capabilities of the platform. * * @hide */ @SystemApi @SystemService(Context.PERMISSION_SERVICE) public final class PermissionManager { /** * {@link android.content.pm.PackageParser} needs access without having a {@link Context}. * * @hide */ public static final SplitPermissionInfo[] SPLIT_PERMISSIONS = new SplitPermissionInfo[]{ // 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, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, android.os.Build.VERSION_CODES.CUR_DEVELOPMENT + 1), new SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS, new String[]{android.Manifest.permission.READ_CALL_LOG}, android.os.Build.VERSION_CODES.JELLY_BEAN), new SplitPermissionInfo(android.Manifest.permission.WRITE_CONTACTS, new String[]{android.Manifest.permission.WRITE_CALL_LOG}, android.os.Build.VERSION_CODES.JELLY_BEAN), new SplitPermissionInfo(Manifest.permission.ACCESS_FINE_LOCATION, new String[]{android.Manifest.permission.ACCESS_BACKGROUND_LOCATION}, android.os.Build.VERSION_CODES.P0), new SplitPermissionInfo(Manifest.permission.ACCESS_COARSE_LOCATION, new String[]{android.Manifest.permission.ACCESS_BACKGROUND_LOCATION}, android.os.Build.VERSION_CODES.P0)}; private final @NonNull Context mContext; /** * Creates a new instance. * * @param context The current context in which to operate. * @hide */ public PermissionManager(@NonNull Context context) { mContext = context; } /** * Get list of permissions that have been split into more granular or dependent permissions. * * <p>E.g. before {@link android.os.Build.VERSION_CODES#P0} an app that was granted * {@link Manifest.permission#ACCESS_COARSE_LOCATION} could access he location while it was in * foreground and background. On platforms after {@link android.os.Build.VERSION_CODES#P0} * the location permission only grants location access while the app is in foreground. This * would break apps that target before {@link android.os.Build.VERSION_CODES#P0}. Hence whenever * such an old app asks for a location permission (i.e. the * {@link SplitPermissionInfo#getRootPermission()}), then the * {@link Manifest.permission#ACCESS_BACKGROUND_LOCATION} permission (inside * {@{@link SplitPermissionInfo#getNewPermissions}) is added. * * <p>Note: Regular apps do not have to worry about this. The platform and permission controller * automatically add the new permissions where needed. * * @return All permissions that are split. */ public @NonNull List<SplitPermissionInfo> getSplitPermissions() { return Arrays.asList(SPLIT_PERMISSIONS); } /** * A permission that was added in a previous API level might have split into several * permissions. This object describes one such split. */ @Immutable public static final class SplitPermissionInfo { private final @NonNull String mRootPerm; private final @NonNull String[] mNewPerms; private final int mTargetSdk; /** * Get the permission that is split. */ public @NonNull String getRootPermission() { return mRootPerm; } /** * Get the permissions that are added. */ public @NonNull String[] getNewPermissions() { return mNewPerms; } /** * Get the target API level when the permission was split. */ public int getTargetSdk() { return mTargetSdk; } private SplitPermissionInfo(@NonNull String rootPerm, @NonNull String[] newPerms, int targetSdk) { mRootPerm = rootPerm; mNewPerms = newPerms; mTargetSdk = targetSdk; } } }