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

Commit f73058df authored by Brian Lee's avatar Brian Lee Committed by Android (Google) Code Review
Browse files

Merge "Update KeyguardManager & FeatureFlagUtils to support remote device lockscreen validation"

parents f1780e12 84ae4818
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -912,6 +912,7 @@ package android.app {
  public class KeyguardManager {
    method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public long addWeakEscrowToken(@NonNull byte[], @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.WeakEscrowTokenActivatedListener);
    method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.content.Intent createConfirmDeviceCredentialForRemoteValidationIntent(@NonNull android.app.StartLockscreenValidationRequest, @NonNull android.content.ComponentName, @Nullable CharSequence, @Nullable CharSequence, @Nullable CharSequence, @Nullable CharSequence);
    method public android.content.Intent createConfirmFactoryResetCredentialIntent(CharSequence, CharSequence, CharSequence);
    method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public int getMinLockLength(boolean, int);
    method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public boolean getPrivateNotificationsAllowed();
+68 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.app.admin.PasswordMetrics;
import android.app.trust.ITrustManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -108,6 +109,13 @@ public class KeyguardManager {
    public static final String ACTION_CONFIRM_FRP_CREDENTIAL =
            "android.app.action.CONFIRM_FRP_CREDENTIAL";

    /**
     * Intent used to prompt user to to validate the credentials of a remote device.
     * @hide
     */
    public static final String ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL =
            "android.app.action.CONFIRM_REMOTE_DEVICE_CREDENTIAL";

    /**
     * A CharSequence dialog title to show to the user when used with a
     * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
@@ -130,10 +138,27 @@ public class KeyguardManager {
    public static final String EXTRA_ALTERNATE_BUTTON_LABEL =
            "android.app.extra.ALTERNATE_BUTTON_LABEL";

    /**
     * A CharSequence label for the checkbox when used with
     * {@link #ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL}
     * @hide
     */
    public static final String EXTRA_CHECKBOX_LABEL = "android.app.extra.CHECKBOX_LABEL";

    /**
     * A {@link StartLockscreenValidationRequest} extra to be sent along with
     * {@link #ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL} containing the data needed to prompt for
     * a remote device's lock screen.
     * @hide
     */
    public static final String EXTRA_START_LOCKSCREEN_VALIDATION_REQUEST =
            "android.app.extra.START_LOCKSCREEN_VALIDATION_REQUEST";

    /**
     * Result code returned by the activity started by
     * {@link #createConfirmFactoryResetCredentialIntent} indicating that the user clicked the
     * alternate button.
     * {@link #createConfirmFactoryResetCredentialIntent} or
     * {@link #createConfirmDeviceCredentialForRemoteValidationIntent}
     * indicating that the user clicked the alternate button.
     *
     * @hide
     */
@@ -331,6 +356,47 @@ public class KeyguardManager {
        return intent;
    }

    /**
     * Get an Intent to launch an activity to prompt the user to confirm the
     * credentials (pin, pattern or password) of a remote device.
     * @param startLockscreenValidationRequest contains information necessary to start remote device
     *                                         credential validation.
     * @param remoteLockscreenValidationServiceComponent
     *          the {@link ComponentName} of the implementation of
     *          {@link android.service.remotelockscreenvalidation.RemoteLockscreenValidationService}
     * @param checkboxLabel if not empty, a checkbox is provided with the given label. When checked,
     *                      the validated remote device credential will be set as the device lock of
     *                      the current device.
     * @param alternateButtonLabel if not empty, a button is provided with the given label. Upon
     *                             clicking this button, the activity returns
     *                             {@link #RESULT_ALTERNATE}.
     * @hide
     */
    @SystemApi
    @RequiresPermission(Manifest.permission.CHECK_REMOTE_LOCKSCREEN)
    @NonNull
    public Intent createConfirmDeviceCredentialForRemoteValidationIntent(
            @NonNull StartLockscreenValidationRequest startLockscreenValidationRequest,
            @NonNull ComponentName remoteLockscreenValidationServiceComponent,
            @Nullable CharSequence title,
            @Nullable CharSequence description,
            @Nullable CharSequence checkboxLabel,
            @Nullable CharSequence alternateButtonLabel) {
        Intent intent = new Intent(ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL)
                .putExtra(
                        EXTRA_START_LOCKSCREEN_VALIDATION_REQUEST, startLockscreenValidationRequest)
                .putExtra(Intent.EXTRA_COMPONENT_NAME, remoteLockscreenValidationServiceComponent)
                .putExtra(EXTRA_TITLE, title)
                .putExtra(EXTRA_DESCRIPTION, description)
                .putExtra(EXTRA_CHECKBOX_LABEL, checkboxLabel)
                .putExtra(EXTRA_ALTERNATE_BUTTON_LABEL, alternateButtonLabel);

        // explicitly set the package for security
        intent.setPackage(getSettingsPackageForIntent(intent));

        return intent;
    }

    /**
     * Controls whether notifications can be shown atop a securely locked screen in their full
     * private form (same as when the device is unlocked).
+9 −0
Original line number Diff line number Diff line
@@ -183,6 +183,14 @@ public class FeatureFlagUtils {
    public static final String SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API =
            "settings_enable_lockscreen_transfer_api";

    /**
     * Flag to enable remote device credential validation
     * @hide
     */
    public static final String SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION =
            "settings_remote_device_credential_validation";


    private static final Map<String, String> DEFAULT_FLAGS;

    static {
@@ -226,6 +234,7 @@ public class FeatureFlagUtils {
        DEFAULT_FLAGS.put(SETTINGS_FLASH_ALERTS, "false");
        DEFAULT_FLAGS.put(SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, "true");
        DEFAULT_FLAGS.put(SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API, "false");
        DEFAULT_FLAGS.put(SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION, "false");
    }

    private static final Set<String> PERSISTENT_FLAGS;
+8 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import com.google.android.collect.Lists;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
@@ -115,6 +116,13 @@ public class LockPatternUtils {
    public static final int CREDENTIAL_TYPE_PIN = 3;
    public static final int CREDENTIAL_TYPE_PASSWORD = 4;

    /**
     * Header used for the encryption and decryption of the device credential for
     * remote device lockscreen validation.
     */
    public static final byte[] ENCRYPTED_REMOTE_CREDENTIALS_HEADER =
            "encrypted_remote_credentials".getBytes(StandardCharsets.UTF_8);

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"CREDENTIAL_TYPE_"}, value = {
            CREDENTIAL_TYPE_NONE,
+1 −3
Original line number Diff line number Diff line
@@ -102,8 +102,6 @@ public class RecoverableKeyStoreManager {
    private static final String TAG = "RecoverableKeyStoreMgr";
    private static final long SYNC_DELAY_MILLIS = 2000;
    private static final int INVALID_REMOTE_GUESS_LIMIT = 5;
    public static final byte[] ENCRYPTED_REMOTE_CREDENTIALS_HEADER =
            "encrypted_remote_credentials".getBytes(StandardCharsets.UTF_8);

    private static RecoverableKeyStoreManager mInstance;

@@ -1055,7 +1053,7 @@ public class RecoverableKeyStoreManager {
            decryptedCredentials = SecureBox.decrypt(
                session.getKeyPair().getPrivate(),
                /* sharedSecret= */ null,
                ENCRYPTED_REMOTE_CREDENTIALS_HEADER,
                LockPatternUtils.ENCRYPTED_REMOTE_CREDENTIALS_HEADER,
                encryptedCredential);
        } catch (NoSuchAlgorithmException e) {
            Log.wtf(TAG, "Missing SecureBox algorithm. AOSP required to support this.", e);
Loading