Merge "Update KeyguardManager & FeatureFlagUtils to support remote device lockscreen validation"
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1462,7 +1462,7 @@ public class RecoverableKeyStoreManagerTest {
|
||||
return SecureBox.encrypt(
|
||||
publicKey,
|
||||
/* sharedSecret= */ null,
|
||||
RecoverableKeyStoreManager.ENCRYPTED_REMOTE_CREDENTIALS_HEADER,
|
||||
LockPatternUtils.ENCRYPTED_REMOTE_CREDENTIALS_HEADER,
|
||||
credentials);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user