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

Commit 5402a800 authored by Eric Biggers's avatar Eric Biggers Committed by Gerrit Code Review
Browse files

Merge changes from topic "locksettings-aosp-4" into main

* changes:
  Load reboot escrow data at PHASE_BOOT_COMPLETED
  Add a verification flow for the user to exit repair mode
  Create a verify flag to support verification for entering repair mode
  Add a settings key to expose the device's repair mode state
  Add a configuration to enable or disable support for repair mode
parents 8469d746 af83f177
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -114,6 +114,26 @@ public class KeyguardManager {
    public static final String ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL =
            "android.app.action.CONFIRM_REMOTE_DEVICE_CREDENTIAL";

    /**
     * Intent used to prompt user for device credential for entering repair
     * mode. If the credential is verified successfully, then the information
     * needed to verify the credential again will be written to a location that
     * is available to repair mode. This makes it possible for repair mode to
     * require that the same credential be provided to exit repair mode.
     * @hide
     */
    public static final String ACTION_PREPARE_REPAIR_MODE_DEVICE_CREDENTIAL =
            "android.app.action.PREPARE_REPAIR_MODE_DEVICE_CREDENTIAL";

    /**
     * Intent used to prompt user for device credential that is written by
     * {@link #ACTION_PREPARE_REPAIR_MODE_DEVICE_CREDENTIAL} for exiting
     * repair mode.
     * @hide
     */
    public static final String ACTION_CONFIRM_REPAIR_MODE_DEVICE_CREDENTIAL =
            "android.app.action.CONFIRM_REPAIR_MODE_DEVICE_CREDENTIAL";

    /**
     * A CharSequence dialog title to show to the user when used with a
     * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
+9 −0
Original line number Diff line number Diff line
@@ -17964,6 +17964,15 @@ public final class Settings {
        public static final String REVIEW_PERMISSIONS_NOTIFICATION_STATE =
                "review_permissions_notification_state";
        /**
         * Whether repair mode is active on the device.
         * <p>
         * Set to 1 for true and 0 for false.
         *
         * @hide
         */
        public static final String REPAIR_MODE_ACTIVE = "repair_mode_active";
        /**
         * Settings migrated from Wear OS settings provider.
         * @hide
+96 −10
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
@@ -160,9 +161,17 @@ public class LockPatternUtils {
     */
    public static final int VERIFY_FLAG_REQUEST_GK_PW_HANDLE = 1 << 0;

    /**
     * Flag provided to {@link #verifyCredential(LockscreenCredential, int, int)} . If set, the
     * method writes the password data to the repair mode file after the credential is verified
     * successfully.
     */
    public static final int VERIFY_FLAG_WRITE_REPAIR_MODE_PW = 1 << 1;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, value = {
            VERIFY_FLAG_REQUEST_GK_PW_HANDLE
            VERIFY_FLAG_REQUEST_GK_PW_HANDLE,
            VERIFY_FLAG_WRITE_REPAIR_MODE_PW
    })
    public @interface VerifyFlag {}

@@ -171,6 +180,11 @@ public class LockPatternUtils {
     */
    public static final int USER_FRP = UserHandle.USER_NULL + 1;

    /**
     * Special user id for triggering the exiting repair mode verification flow.
     */
    public static final int USER_REPAIR_MODE = UserHandle.USER_NULL + 2;

    public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
    @Deprecated
    public final static String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate";
@@ -200,6 +214,8 @@ public class LockPatternUtils {
    public static final String CURRENT_LSKF_BASED_PROTECTOR_ID_KEY = "sp-handle";
    public static final String PASSWORD_HISTORY_DELIMITER = ",";

    private static final String GSI_RUNNING_PROP = "ro.gsid.image_running";

    /**
     * drives the pin auto confirmation feature availability in code logic.
     */
@@ -388,7 +404,7 @@ public class LockPatternUtils {

    @UnsupportedAppUsage
    public void reportFailedPasswordAttempt(int userId) {
        if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
        if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
            return;
        }
        getDevicePolicyManager().reportFailedPasswordAttempt(userId);
@@ -397,7 +413,7 @@ public class LockPatternUtils {

    @UnsupportedAppUsage
    public void reportSuccessfulPasswordAttempt(int userId) {
        if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
        if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
            return;
        }
        getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
@@ -405,21 +421,21 @@ public class LockPatternUtils {
    }

    public void reportPasswordLockout(int timeoutMs, int userId) {
        if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
        if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
            return;
        }
        getTrustManager().reportUnlockLockout(timeoutMs, userId);
    }

    public int getCurrentFailedPasswordAttempts(int userId) {
        if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
        if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
            return 0;
        }
        return getDevicePolicyManager().getCurrentFailedPasswordAttempts(userId);
    }

    public int getMaximumFailedPasswordsForWipe(int userId) {
        if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
        if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
            return 0;
        }
        return getDevicePolicyManager().getMaximumFailedPasswordsForWipe(
@@ -739,6 +755,17 @@ public class LockPatternUtils {
        }
    }

    /** Returns the credential type corresponding to the given PIN or password quality. */
    public static int pinOrPasswordQualityToCredentialType(int quality) {
        if (isQualityAlphabeticPassword(quality)) {
            return CREDENTIAL_TYPE_PASSWORD;
        }
        if (isQualityNumericPin(quality)) {
            return CREDENTIAL_TYPE_PIN;
        }
        throw new IllegalArgumentException("Quality is neither Pin nor password: " + quality);
    }

    /**
     * Save a new lockscreen credential.
     *
@@ -971,7 +998,7 @@ public class LockPatternUtils {
                }
                @Override
                public boolean shouldBypassCache(Integer userHandle) {
                    return userHandle == USER_FRP;
                    return isSpecialUserId(userHandle);
                }
            };

@@ -1078,9 +1105,10 @@ public class LockPatternUtils {
    @UnsupportedAppUsage
    public long setLockoutAttemptDeadline(int userId, int timeoutMs) {
        final long deadline = SystemClock.elapsedRealtime() + timeoutMs;
        if (userId == USER_FRP) {
            // For secure password storage (that is required for FRP), the underlying storage also
            // enforces the deadline. Since we cannot store settings for the FRP user, don't.
        if (isSpecialUserId(userId)) {
            // For secure password storage (that is required for special users such as FRP), the
            // underlying storage also enforces the deadline. Since we cannot store settings
            // for special users, don't.
            return deadline;
        }
        mLockoutDeadlines.put(userId, deadline);
@@ -1818,6 +1846,64 @@ public class LockPatternUtils {
                com.android.internal.R.bool.config_enableCredentialFactoryResetProtection);
    }

    /**
     * Return {@code true} if repair mode is supported by the device.
     */
    public static boolean isRepairModeSupported(Context context) {
        return context.getResources().getBoolean(
                com.android.internal.R.bool.config_repairModeSupported);
    }

    /**
     * Return {@code true} if repair mode is active on the device.
     */
    public static boolean isRepairModeActive(Context context) {
        return Settings.Global.getInt(context.getContentResolver(),
                Settings.Global.REPAIR_MODE_ACTIVE, /* def= */ 0) > 0;
    }

    /**
     * Return {@code true} if repair mode is supported by the device and the user has been granted
     * admin privileges.
     */
    public static boolean canUserEnterRepairMode(Context context, UserInfo info) {
        return info != null && info.isAdmin() && isRepairModeSupported(context);
    }

    /**
     * Return {@code true} if GSI is running on the device.
     */
    public static boolean isGsiRunning() {
        return SystemProperties.getInt(GSI_RUNNING_PROP, 0) > 0;
    }

    /**
     * Return {@code true} if the given user id is a special user such as {@link #USER_FRP}.
     */
    public static boolean isSpecialUserId(int userId) {
        return isSpecialUserId(/* context= */ null, userId, /* checkDeviceSupported= */ false);
    }

    /**
     * Return {@code true} if the given user id is a special user for the verification flow.
     *
     * @param checkDeviceSupported {@code true} to check the specified user is supported
     *                             by the device.
     */
    private static boolean isSpecialUserId(@Nullable Context context, int userId,
            boolean checkDeviceSupported) {
        switch (userId) {
            case USER_FRP:
                if (checkDeviceSupported) return frpCredentialEnabled(context);
                return true;

            case USER_REPAIR_MODE:
                if (checkDeviceSupported) return isRepairModeSupported(context);
                return true;
        }
        return false;
    }

    /**
     * Attempt to rederive the unified work challenge for the specified profile user and unlock the
     * user. If successful, this would allow the user to leave quiet mode automatically without
+5 −0
Original line number Diff line number Diff line
@@ -6467,4 +6467,9 @@
    <!-- Whether the AOSP support for app cloning building blocks is to be enabled for the
         device. -->
    <bool name="config_enableAppCloningBuildingBlocks">true</bool>

    <!-- Enables or disables support for repair mode. The feature creates a secure
         environment to protect the user's privacy when the device is being repaired.
         Off by default, since OEMs may have had a similar feature on their devices. -->
    <bool name="config_repairModeSupported">false</bool>
</resources>
+2 −0
Original line number Diff line number Diff line
@@ -4917,6 +4917,8 @@

  <java-symbol type="bool" name="config_safetyProtectionEnabled" />

  <java-symbol type="bool" name="config_repairModeSupported" />

  <java-symbol type="string" name="config_devicePolicyManagementUpdater" />

  <java-symbol type="string" name="config_deviceSpecificDeviceStatePolicyProvider" />
Loading