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

Commit 43300b49 authored by Grace Cheng's avatar Grace Cheng
Browse files

Define Secure Lock Device API surface

Secure Lock is a new feature that enables users to remotely lock
down their mobile device via authorized clients into an enhanced
security state, which restricts access to sensitive data (app
notifications, widgets, quick settings, assistant, etc) and requires
both credential and biometric authentication for device entry.

This change introduces a new AuthenticationPolicyManager, which
external clients will use to call into SecureLockDeviceService via
AuthenticationPolicyService. SecureLockDeviceService implements the new
enableSecureLockDevice and disableSecureLockDevice API methods, which
currently have a placeholder no-op implementation that will be filled
out at a later time.

Bug: 373422357
API-Coverage-Bug: 376456619
Flag: android.security.secure_lockdown
Test: atest AuthenticationPolicyServiceTest
Ignore-AOSP-First: adding flag to security package
Change-Id: I7d2c97a8f51cb8a4475761a6c04ce9f32b38fd19
parent 0e92f936
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -3870,6 +3870,7 @@ package android.content {
    field public static final String APP_INTEGRITY_SERVICE = "app_integrity";
    field public static final String APP_PREDICTION_SERVICE = "app_prediction";
    field public static final String AUDIO_DEVICE_VOLUME_SERVICE = "audio_device_volume";
    field @FlaggedApi("android.security.secure_lockdown") public static final String AUTHENTICATION_POLICY_SERVICE = "authentication_policy";
    field public static final String BACKUP_SERVICE = "backup";
    field public static final String BATTERY_STATS_SERVICE = "batterystats";
    field public static final int BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS = 1048576; // 0x100000
@@ -12859,6 +12860,36 @@ package android.security.advancedprotection {
}
package android.security.authenticationpolicy {
  @FlaggedApi("android.security.secure_lockdown") public final class AuthenticationPolicyManager {
    method @FlaggedApi("android.security.secure_lockdown") @RequiresPermission(android.Manifest.permission.MANAGE_SECURE_LOCK_DEVICE) public int disableSecureLockDevice(@NonNull android.security.authenticationpolicy.DisableSecureLockDeviceParams);
    method @FlaggedApi("android.security.secure_lockdown") @RequiresPermission(android.Manifest.permission.MANAGE_SECURE_LOCK_DEVICE) public int enableSecureLockDevice(@NonNull android.security.authenticationpolicy.EnableSecureLockDeviceParams);
    field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_ALREADY_ENABLED = 6; // 0x6
    field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_INSUFFICIENT_BIOMETRICS = 5; // 0x5
    field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_INVALID_PARAMS = 3; // 0x3
    field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_NO_BIOMETRICS_ENROLLED = 4; // 0x4
    field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_UNKNOWN = 0; // 0x0
    field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_UNSUPPORTED = 2; // 0x2
    field @FlaggedApi("android.security.secure_lockdown") public static final int SUCCESS = 1; // 0x1
  }
  @FlaggedApi("android.security.secure_lockdown") public final class DisableSecureLockDeviceParams implements android.os.Parcelable {
    ctor public DisableSecureLockDeviceParams(@NonNull String);
    method public int describeContents();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.security.authenticationpolicy.DisableSecureLockDeviceParams> CREATOR;
  }
  @FlaggedApi("android.security.secure_lockdown") public final class EnableSecureLockDeviceParams implements android.os.Parcelable {
    ctor public EnableSecureLockDeviceParams(@NonNull String);
    method public int describeContents();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.security.authenticationpolicy.EnableSecureLockDeviceParams> CREATOR;
  }
}
package android.security.forensic {
  @FlaggedApi("android.security.afl_api") public class ForensicManager {
+21 −0
Original line number Diff line number Diff line
@@ -241,6 +241,8 @@ import android.security.advancedprotection.AdvancedProtectionManager;
import android.security.advancedprotection.IAdvancedProtectionService;
import android.security.attestationverification.AttestationVerificationManager;
import android.security.attestationverification.IAttestationVerificationManagerService;
import android.security.authenticationpolicy.AuthenticationPolicyManager;
import android.security.authenticationpolicy.IAuthenticationPolicyService;
import android.security.forensic.ForensicManager;
import android.security.forensic.IForensicService;
import android.security.keystore.KeyStoreManager;
@@ -1025,6 +1027,25 @@ public final class SystemServiceRegistry {
                    }
                });

        registerService(Context.AUTHENTICATION_POLICY_SERVICE,
                AuthenticationPolicyManager.class,
                new CachedServiceFetcher<AuthenticationPolicyManager>() {
                    @Override
                    public AuthenticationPolicyManager createService(ContextImpl ctx)
                            throws ServiceNotFoundException {
                        if (!android.security.Flags.secureLockdown()) {
                            throw new ServiceNotFoundException(
                                    Context.AUTHENTICATION_POLICY_SERVICE);
                        }

                        final IBinder binder = ServiceManager.getServiceOrThrow(
                                Context.AUTHENTICATION_POLICY_SERVICE);
                        final IAuthenticationPolicyService service =
                                IAuthenticationPolicyService.Stub.asInterface(binder);
                        return new AuthenticationPolicyManager(ctx.getOuterContext(), service);
                    }
                });

        registerService(Context.TV_INTERACTIVE_APP_SERVICE, TvInteractiveAppManager.class,
                new CachedServiceFetcher<TvInteractiveAppManager>() {
            @Override
+21 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.content;

import static android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER;
import static android.content.flags.Flags.FLAG_ENABLE_BIND_PACKAGE_ISOLATED_PROCESS;
import static android.security.Flags.FLAG_SECURE_LOCKDOWN;

import android.annotation.AttrRes;
import android.annotation.CallbackExecutor;
@@ -4256,6 +4257,7 @@ public abstract class Context {
            FINGERPRINT_SERVICE,
            //@hide: FACE_SERVICE,
            BIOMETRIC_SERVICE,
            AUTHENTICATION_POLICY_SERVICE,
            MEDIA_ROUTER_SERVICE,
            TELEPHONY_SERVICE,
            TELEPHONY_SUBSCRIPTION_SERVICE,
@@ -4437,6 +4439,9 @@ public abstract class Context {
     * web domain approval state.
     * <dt> {@link #DISPLAY_HASH_SERVICE} ("display_hash")
     * <dd> A {@link android.view.displayhash.DisplayHashManager} for management of display hashes.
     * <dt> {@link #AUTHENTICATION_POLICY_SERVICE} ("authentication_policy")
     * <dd> A {@link android.security.authenticationpolicy.AuthenticationPolicyManager}
     * for managing authentication related policies on the device.
     * </dl>
     *
     * <p>Note:  System services obtained via this API may be closely associated with
@@ -4521,6 +4526,8 @@ public abstract class Context {
     * @see android.content.pm.verify.domain.DomainVerificationManager
     * @see #DISPLAY_HASH_SERVICE
     * @see android.view.displayhash.DisplayHashManager
     * @see #AUTHENTICATION_POLICY_SERVICE
     * @see android.security.authenticationpolicy.AuthenticationPolicyManager
     */
    // TODO(b/347269120): Re-add @Nullable
    public abstract Object getSystemService(@ServiceName @NonNull String name);
@@ -4543,7 +4550,8 @@ public abstract class Context {
     * {@link android.os.BatteryManager}, {@link android.app.job.JobScheduler},
     * {@link android.app.usage.NetworkStatsManager},
     * {@link android.content.pm.verify.domain.DomainVerificationManager},
     * {@link android.view.displayhash.DisplayHashManager}.
     * {@link android.view.displayhash.DisplayHashManager}
     * {@link android.security.authenticationpolicy.AuthenticationPolicyManager}.
     * </p>
     *
     * <p>
@@ -5182,6 +5190,18 @@ public abstract class Context {
     */
    public static final String AUTH_SERVICE = "auth";

    /**
     * Use with {@link #getSystemService(String)} to retrieve an {@link
     * android.security.authenticationpolicy.AuthenticationPolicyManager}.
     * @see #getSystemService
     * @see android.security.authenticationpolicy.AuthenticationPolicyManager
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(FLAG_SECURE_LOCKDOWN)
    public static final String AUTHENTICATION_POLICY_SERVICE = "authentication_policy";

    /**
     * Use with {@link #getSystemService(String)} to retrieve a
     * {@link android.hardware.fingerprint.FingerprintManager} for handling management
+237 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.security.authenticationpolicy;

import static android.Manifest.permission.MANAGE_SECURE_LOCK_DEVICE;
import static android.security.Flags.FLAG_SECURE_LOCKDOWN;

import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * AuthenticationPolicyManager is a centralized interface for managing authentication related
 * policies on the device. This includes device locking capabilities to protect users in "at risk"
 * environments.
 *
 * AuthenticationPolicyManager is designed to protect Android users by integrating with apps and
 * key system components, such as the lock screen. It is not related to enterprise control surfaces
 * and does not offer additional administrative controls.
 *
 * <p>
 * To use this class, call {@link #enableSecureLockDevice} to enable secure lock on the device.
 * This will require the caller to have the
 * {@link android.Manifest.permission#MANAGE_SECURE_LOCK_DEVICE} permission.
 *
 * <p>
 * To disable secure lock on the device, call {@link #disableSecureLockDevice}. This will require
 * the caller to have the {@link android.Manifest.permission#MANAGE_SECURE_LOCK_DEVICE} permission.
 *
 * @hide
 */
@SystemApi
@FlaggedApi(FLAG_SECURE_LOCKDOWN)
@SystemService(Context.AUTHENTICATION_POLICY_SERVICE)
public final class AuthenticationPolicyManager {
    private static final String TAG = "AuthenticationPolicyManager";

    @NonNull private final IAuthenticationPolicyService mAuthenticationPolicyService;
    @NonNull private final Context mContext;

    /**
     * Error result code for {@link #enableSecureLockDevice} and {@link
     * #disableSecureLockDevice}.
     *
     * Secure lock device request status unknown.
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(FLAG_SECURE_LOCKDOWN)
    public static final int ERROR_UNKNOWN = 0;

    /**
     * Success result code for {@link #enableSecureLockDevice} and {@link #disableSecureLockDevice}.
     *
     * Secure lock device request successful.
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(FLAG_SECURE_LOCKDOWN)
    public static final int SUCCESS = 1;

    /**
     * Error result code for {@link #enableSecureLockDevice} and {@link #disableSecureLockDevice}.
     *
     * Secure lock device is unsupported.
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(FLAG_SECURE_LOCKDOWN)
    public static final int ERROR_UNSUPPORTED = 2;


    /**
     * Error result code for {@link #enableSecureLockDevice} and {@link #disableSecureLockDevice}.
     *
     * Invalid secure lock device request params provided.
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(FLAG_SECURE_LOCKDOWN)
    public static final int ERROR_INVALID_PARAMS = 3;


    /**
     * Error result code for {@link #enableSecureLockDevice} and {@link #disableSecureLockDevice}.
     *
     * Secure lock device is unavailable because there are no biometrics enrolled on the device.
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(FLAG_SECURE_LOCKDOWN)
    public static final int ERROR_NO_BIOMETRICS_ENROLLED = 4;

    /**
     * Error result code for {@link #enableSecureLockDevice} and {@link #disableSecureLockDevice}.
     *
     * Secure lock device is unavailable because the device has no biometric hardware or the
     * biometric sensors do not meet
     * {@link android.hardware.biometrics.BiometricManager.Authenticators#BIOMETRIC_STRONG}
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(FLAG_SECURE_LOCKDOWN)
    public static final int ERROR_INSUFFICIENT_BIOMETRICS = 5;

    /**
     * Error result code for {@link #enableSecureLockDevice}.
     *
     * Secure lock is already enabled.
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(FLAG_SECURE_LOCKDOWN)
    public static final int ERROR_ALREADY_ENABLED = 6;

    /**
     * Communicates the current status of a request to enable secure lock on the device.
     *
     * @hide
     */
    @IntDef(prefix = {"ENABLE_SECURE_LOCK_DEVICE_STATUS_"}, value = {
            ERROR_UNKNOWN,
            SUCCESS,
            ERROR_UNSUPPORTED,
            ERROR_INVALID_PARAMS,
            ERROR_NO_BIOMETRICS_ENROLLED,
            ERROR_INSUFFICIENT_BIOMETRICS,
            ERROR_ALREADY_ENABLED
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EnableSecureLockDeviceRequestStatus {}

    /**
     * Communicates the current status of a request to disable secure lock on the device.
     *
     * @hide
     */
    @IntDef(prefix = {"DISABLE_SECURE_LOCK_DEVICE_STATUS_"}, value = {
            ERROR_UNKNOWN,
            SUCCESS,
            ERROR_UNSUPPORTED,
            ERROR_INVALID_PARAMS,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface DisableSecureLockDeviceRequestStatus {}

    /** @hide */
    public AuthenticationPolicyManager(@NonNull Context context,
            @NonNull IAuthenticationPolicyService authenticationPolicyService) {
        mContext = context;
        mAuthenticationPolicyService = authenticationPolicyService;
    }

    /**
     * Called by a privileged component to remotely enable secure lock on the device.
     *
     * Secure lock is an enhanced security state that restricts access to sensitive data (app
     * notifications, widgets, quick settings, assistant, etc) and requires multi-factor
     * authentication for device entry, such as
     * {@link android.hardware.biometrics.BiometricManager.Authenticators#DEVICE_CREDENTIAL} and
     * {@link android.hardware.biometrics.BiometricManager.Authenticators#BIOMETRIC_STRONG}.
     *
     * If secure lock is already enabled when this method is called, it will return
     * {@link ERROR_ALREADY_ENABLED}.
     *
     * @param params EnableSecureLockDeviceParams for caller to supply params related to the secure
     *               lock device request
     * @return @EnableSecureLockDeviceRequestStatus int indicating the result of the secure lock
     * device request
     *
     * @hide
     */
    @EnableSecureLockDeviceRequestStatus
    @RequiresPermission(MANAGE_SECURE_LOCK_DEVICE)
    @SystemApi
    @FlaggedApi(FLAG_SECURE_LOCKDOWN)
    public int enableSecureLockDevice(@NonNull EnableSecureLockDeviceParams params) {
        try {
            return mAuthenticationPolicyService.enableSecureLockDevice(params);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Called by a privileged component to disable secure lock on the device.
     *
     * If secure lock is already disabled when this method is called, it will return
     * {@link SUCCESS}.
     *
     * @param params @DisableSecureLockDeviceParams for caller to supply params related to the
     *               secure lock device request
     * @return @DisableSecureLockDeviceRequestStatus int indicating the result of the secure lock
     * device request
     *
     * @hide
     */
    @DisableSecureLockDeviceRequestStatus
    @RequiresPermission(MANAGE_SECURE_LOCK_DEVICE)
    @SystemApi
    @FlaggedApi(FLAG_SECURE_LOCKDOWN)
    public int disableSecureLockDevice(@NonNull DisableSecureLockDeviceParams params) {
        try {
            return mAuthenticationPolicyService.disableSecureLockDevice(params);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}
+21 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.security.authenticationpolicy;

/**
 * @hide
 */
parcelable DisableSecureLockDeviceParams;
 No newline at end of file
Loading