Loading core/java/android/app/SystemServiceRegistry.java +9 −0 Original line number Diff line number Diff line Loading @@ -171,6 +171,7 @@ import android.os.IThermalService; import android.os.IUserManager; import android.os.IncidentManager; import android.os.PerformanceHintManager; import android.os.PermissionEnforcer; import android.os.PowerManager; import android.os.RecoverySystem; import android.os.ServiceManager; Loading Loading @@ -1351,6 +1352,14 @@ public final class SystemServiceRegistry { return new PermissionCheckerManager(ctx.getOuterContext()); }}); registerService(Context.PERMISSION_ENFORCER_SERVICE, PermissionEnforcer.class, new CachedServiceFetcher<PermissionEnforcer>() { @Override public PermissionEnforcer createService(ContextImpl ctx) throws ServiceNotFoundException { return new PermissionEnforcer(ctx.getOuterContext()); }}); registerService(Context.DYNAMIC_SYSTEM_SERVICE, DynamicSystemManager.class, new CachedServiceFetcher<DynamicSystemManager>() { @Override Loading core/java/android/content/Context.java +8 −0 Original line number Diff line number Diff line Loading @@ -5134,6 +5134,14 @@ public abstract class Context { */ public static final String PERMISSION_CHECKER_SERVICE = "permission_checker"; /** * Official published name of the (internal) permission enforcer service. * * @see #getSystemService(String) * @hide */ public static final String PERMISSION_ENFORCER_SERVICE = "permission_enforcer"; /** * Use with {@link #getSystemService(String) to retrieve an * {@link android.apphibernation.AppHibernationManager}} for Loading core/java/android/os/OWNERS +4 −0 Original line number Diff line number Diff line Loading @@ -70,3 +70,7 @@ per-file Vintf* = file:/platform/system/libvintf:/OWNERS # Tracing per-file Trace.java = file:/TRACE_OWNERS # PermissionEnforcer per-file PermissionEnforcer.java = tweek@google.com, brufino@google.com per-file PermissionEnforcer.java = file:/core/java/android/permission/OWNERS core/java/android/os/PermissionEnforcer.java 0 → 100644 +101 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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.os; import android.annotation.NonNull; import android.annotation.SystemService; import android.content.AttributionSource; import android.content.Context; import android.content.PermissionChecker; import android.permission.PermissionCheckerManager; /** * PermissionEnforcer check permissions for AIDL-generated services which use * the @EnforcePermission annotation. * * <p>AIDL services may be annotated with @EnforcePermission which will trigger * the generation of permission check code. This generated code relies on * PermissionEnforcer to validate the permissions. The methods available are * purposely similar to the AIDL annotation syntax. * * @see android.permission.PermissionManager * * @hide */ @SystemService(Context.PERMISSION_ENFORCER_SERVICE) public class PermissionEnforcer { private final Context mContext; /** Protected constructor. Allows subclasses to instantiate an object * without using a Context. */ protected PermissionEnforcer() { mContext = null; } /** Constructor, prefer using the fromContext static method when possible */ public PermissionEnforcer(@NonNull Context context) { mContext = context; } @PermissionCheckerManager.PermissionResult protected int checkPermission(@NonNull String permission, @NonNull AttributionSource source) { return PermissionChecker.checkPermissionForDataDelivery( mContext, permission, PermissionChecker.PID_UNKNOWN, source, "" /* message */); } public void enforcePermission(@NonNull String permission, @NonNull AttributionSource source) throws SecurityException { int result = checkPermission(permission, source); if (result != PermissionCheckerManager.PERMISSION_GRANTED) { throw new SecurityException("Access denied, requires: " + permission); } } public void enforcePermissionAllOf(@NonNull String[] permissions, @NonNull AttributionSource source) throws SecurityException { for (String permission : permissions) { int result = checkPermission(permission, source); if (result != PermissionCheckerManager.PERMISSION_GRANTED) { throw new SecurityException("Access denied, requires: allOf={" + String.join(", ", permissions) + "}"); } } } public void enforcePermissionAnyOf(@NonNull String[] permissions, @NonNull AttributionSource source) throws SecurityException { for (String permission : permissions) { int result = checkPermission(permission, source); if (result == PermissionCheckerManager.PERMISSION_GRANTED) { return; } } throw new SecurityException("Access denied, requires: anyOf={" + String.join(", ", permissions) + "}"); } /** * Returns a new PermissionEnforcer based on a Context. * * @hide */ public static PermissionEnforcer fromContext(@NonNull Context context) { return context.getSystemService(PermissionEnforcer.class); } } Loading
core/java/android/app/SystemServiceRegistry.java +9 −0 Original line number Diff line number Diff line Loading @@ -171,6 +171,7 @@ import android.os.IThermalService; import android.os.IUserManager; import android.os.IncidentManager; import android.os.PerformanceHintManager; import android.os.PermissionEnforcer; import android.os.PowerManager; import android.os.RecoverySystem; import android.os.ServiceManager; Loading Loading @@ -1351,6 +1352,14 @@ public final class SystemServiceRegistry { return new PermissionCheckerManager(ctx.getOuterContext()); }}); registerService(Context.PERMISSION_ENFORCER_SERVICE, PermissionEnforcer.class, new CachedServiceFetcher<PermissionEnforcer>() { @Override public PermissionEnforcer createService(ContextImpl ctx) throws ServiceNotFoundException { return new PermissionEnforcer(ctx.getOuterContext()); }}); registerService(Context.DYNAMIC_SYSTEM_SERVICE, DynamicSystemManager.class, new CachedServiceFetcher<DynamicSystemManager>() { @Override Loading
core/java/android/content/Context.java +8 −0 Original line number Diff line number Diff line Loading @@ -5134,6 +5134,14 @@ public abstract class Context { */ public static final String PERMISSION_CHECKER_SERVICE = "permission_checker"; /** * Official published name of the (internal) permission enforcer service. * * @see #getSystemService(String) * @hide */ public static final String PERMISSION_ENFORCER_SERVICE = "permission_enforcer"; /** * Use with {@link #getSystemService(String) to retrieve an * {@link android.apphibernation.AppHibernationManager}} for Loading
core/java/android/os/OWNERS +4 −0 Original line number Diff line number Diff line Loading @@ -70,3 +70,7 @@ per-file Vintf* = file:/platform/system/libvintf:/OWNERS # Tracing per-file Trace.java = file:/TRACE_OWNERS # PermissionEnforcer per-file PermissionEnforcer.java = tweek@google.com, brufino@google.com per-file PermissionEnforcer.java = file:/core/java/android/permission/OWNERS
core/java/android/os/PermissionEnforcer.java 0 → 100644 +101 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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.os; import android.annotation.NonNull; import android.annotation.SystemService; import android.content.AttributionSource; import android.content.Context; import android.content.PermissionChecker; import android.permission.PermissionCheckerManager; /** * PermissionEnforcer check permissions for AIDL-generated services which use * the @EnforcePermission annotation. * * <p>AIDL services may be annotated with @EnforcePermission which will trigger * the generation of permission check code. This generated code relies on * PermissionEnforcer to validate the permissions. The methods available are * purposely similar to the AIDL annotation syntax. * * @see android.permission.PermissionManager * * @hide */ @SystemService(Context.PERMISSION_ENFORCER_SERVICE) public class PermissionEnforcer { private final Context mContext; /** Protected constructor. Allows subclasses to instantiate an object * without using a Context. */ protected PermissionEnforcer() { mContext = null; } /** Constructor, prefer using the fromContext static method when possible */ public PermissionEnforcer(@NonNull Context context) { mContext = context; } @PermissionCheckerManager.PermissionResult protected int checkPermission(@NonNull String permission, @NonNull AttributionSource source) { return PermissionChecker.checkPermissionForDataDelivery( mContext, permission, PermissionChecker.PID_UNKNOWN, source, "" /* message */); } public void enforcePermission(@NonNull String permission, @NonNull AttributionSource source) throws SecurityException { int result = checkPermission(permission, source); if (result != PermissionCheckerManager.PERMISSION_GRANTED) { throw new SecurityException("Access denied, requires: " + permission); } } public void enforcePermissionAllOf(@NonNull String[] permissions, @NonNull AttributionSource source) throws SecurityException { for (String permission : permissions) { int result = checkPermission(permission, source); if (result != PermissionCheckerManager.PERMISSION_GRANTED) { throw new SecurityException("Access denied, requires: allOf={" + String.join(", ", permissions) + "}"); } } } public void enforcePermissionAnyOf(@NonNull String[] permissions, @NonNull AttributionSource source) throws SecurityException { for (String permission : permissions) { int result = checkPermission(permission, source); if (result == PermissionCheckerManager.PERMISSION_GRANTED) { return; } } throw new SecurityException("Access denied, requires: anyOf={" + String.join(", ", permissions) + "}"); } /** * Returns a new PermissionEnforcer based on a Context. * * @hide */ public static PermissionEnforcer fromContext(@NonNull Context context) { return context.getSystemService(PermissionEnforcer.class); } }