Add RemoteLockscreenValidationFragment to help retain remote lockscreen am: 2eb8ed2488
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/22390454 Change-Id: I58487aef2bc252448119e48c7a2f2bedc3a710b9 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
// TODO (b/35202196): move this class out of the root of the package.
|
// TODO (b/35202196): move this class out of the root of the package.
|
||||||
package com.android.settings.password;
|
package com.android.settings.password;
|
||||||
|
|
||||||
|
import static android.app.Activity.RESULT_FIRST_USER;
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LOCK_ATTEMPTS_FAILED;
|
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LOCK_ATTEMPTS_FAILED;
|
||||||
|
|
||||||
import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
|
import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
|
||||||
@@ -24,7 +25,6 @@ import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.app.RemoteLockscreenValidationResult;
|
|
||||||
import android.app.RemoteLockscreenValidationSession;
|
import android.app.RemoteLockscreenValidationSession;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.app.admin.ManagedSubscriptionsPolicy;
|
import android.app.admin.ManagedSubscriptionsPolicy;
|
||||||
@@ -38,7 +38,6 @@ import android.os.Bundle;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.service.remotelockscreenvalidation.IRemoteLockscreenValidationCallback;
|
|
||||||
import android.service.remotelockscreenvalidation.RemoteLockscreenValidationClient;
|
import android.service.remotelockscreenvalidation.RemoteLockscreenValidationClient;
|
||||||
import android.telecom.TelecomManager;
|
import android.telecom.TelecomManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -55,14 +54,11 @@ import androidx.fragment.app.FragmentManager;
|
|||||||
|
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.internal.widget.LockscreenCredential;
|
import com.android.internal.widget.LockscreenCredential;
|
||||||
import com.android.security.SecureBox;
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
import com.android.settings.core.InstrumentedFragment;
|
import com.android.settings.core.InstrumentedFragment;
|
||||||
|
|
||||||
import java.security.InvalidKeyException;
|
import com.google.android.setupdesign.GlifLayout;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base fragment to be shared for PIN/Pattern/Password confirmation fragments.
|
* Base fragment to be shared for PIN/Pattern/Password confirmation fragments.
|
||||||
@@ -89,9 +85,13 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
/** Time we wait before clearing a wrong input attempt (e.g. pattern) and the error message. */
|
/** Time we wait before clearing a wrong input attempt (e.g. pattern) and the error message. */
|
||||||
protected static final long CLEAR_WRONG_ATTEMPT_TIMEOUT_MS = 3000;
|
protected static final long CLEAR_WRONG_ATTEMPT_TIMEOUT_MS = 3000;
|
||||||
|
|
||||||
|
protected static final String FRAGMENT_TAG_REMOTE_LOCKSCREEN_VALIDATION =
|
||||||
|
"remote_lockscreen_validation";
|
||||||
|
|
||||||
protected boolean mReturnCredentials = false;
|
protected boolean mReturnCredentials = false;
|
||||||
protected boolean mReturnGatekeeperPassword = false;
|
protected boolean mReturnGatekeeperPassword = false;
|
||||||
protected boolean mForceVerifyPath = false;
|
protected boolean mForceVerifyPath = false;
|
||||||
|
protected GlifLayout mGlifLayout;
|
||||||
protected CheckBox mCheckBox;
|
protected CheckBox mCheckBox;
|
||||||
protected Button mCancelButton;
|
protected Button mCancelButton;
|
||||||
/** Button allowing managed profile password reset, null when is not shown. */
|
/** Button allowing managed profile password reset, null when is not shown. */
|
||||||
@@ -109,8 +109,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
protected BiometricManager mBiometricManager;
|
protected BiometricManager mBiometricManager;
|
||||||
@Nullable protected RemoteLockscreenValidationSession mRemoteLockscreenValidationSession;
|
@Nullable protected RemoteLockscreenValidationSession mRemoteLockscreenValidationSession;
|
||||||
/** Credential saved so the credential can be set for device if remote validation passes */
|
/** Credential saved so the credential can be set for device if remote validation passes */
|
||||||
@Nullable protected LockscreenCredential mDeviceCredentialGuess;
|
|
||||||
@Nullable protected RemoteLockscreenValidationClient mRemoteLockscreenValidationClient;
|
@Nullable protected RemoteLockscreenValidationClient mRemoteLockscreenValidationClient;
|
||||||
|
protected RemoteLockscreenValidationFragment mRemoteLockscreenValidationFragment;
|
||||||
|
|
||||||
private boolean isInternalActivity() {
|
private boolean isInternalActivity() {
|
||||||
return (getActivity() instanceof ConfirmLockPassword.InternalActivity)
|
return (getActivity() instanceof ConfirmLockPassword.InternalActivity)
|
||||||
@@ -136,8 +136,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
FeatureFlagUtils.SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION)) {
|
FeatureFlagUtils.SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION)) {
|
||||||
mRemoteValidation = true;
|
mRemoteValidation = true;
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Remote device credential validation not enabled.");
|
onRemoteLockscreenValidationFailure(
|
||||||
getActivity().finish();
|
"Remote lockscreen validation not enabled.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mRemoteValidation) {
|
if (mRemoteValidation) {
|
||||||
@@ -146,23 +146,31 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
RemoteLockscreenValidationSession.class);
|
RemoteLockscreenValidationSession.class);
|
||||||
if (mRemoteLockscreenValidationSession == null
|
if (mRemoteLockscreenValidationSession == null
|
||||||
|| mRemoteLockscreenValidationSession.getRemainingAttempts() == 0) {
|
|| mRemoteLockscreenValidationSession.getRemainingAttempts() == 0) {
|
||||||
Log.e(TAG, "RemoteLockscreenValidationSession is null or "
|
onRemoteLockscreenValidationFailure("RemoteLockscreenValidationSession is null or "
|
||||||
+ "no more attempts for remote lockscreen validation.");
|
+ "no more attempts for remote lockscreen validation.");
|
||||||
getActivity().finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ComponentName remoteLockscreenValidationServiceComponent =
|
ComponentName remoteLockscreenValidationServiceComponent =
|
||||||
intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME, ComponentName.class);
|
intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME, ComponentName.class);
|
||||||
if (remoteLockscreenValidationServiceComponent == null) {
|
if (remoteLockscreenValidationServiceComponent == null) {
|
||||||
Log.e(TAG, "RemoteLockscreenValidationService ComponentName is null");
|
onRemoteLockscreenValidationFailure(
|
||||||
getActivity().finish();
|
"RemoteLockscreenValidationService ComponentName is null");
|
||||||
}
|
}
|
||||||
mRemoteLockscreenValidationClient = RemoteLockscreenValidationClient
|
mRemoteLockscreenValidationClient = RemoteLockscreenValidationClient
|
||||||
.create(getContext(), remoteLockscreenValidationServiceComponent);
|
.create(getContext(), remoteLockscreenValidationServiceComponent);
|
||||||
if (!mRemoteLockscreenValidationClient.isServiceAvailable()) {
|
if (!mRemoteLockscreenValidationClient.isServiceAvailable()) {
|
||||||
Log.e(TAG, String.format("RemoteLockscreenValidationService at %s is not available",
|
onRemoteLockscreenValidationFailure(String.format(
|
||||||
|
"RemoteLockscreenValidationService at %s is not available",
|
||||||
remoteLockscreenValidationServiceComponent.getClassName()));
|
remoteLockscreenValidationServiceComponent.getClassName()));
|
||||||
getActivity().finish();
|
}
|
||||||
|
|
||||||
|
mRemoteLockscreenValidationFragment =
|
||||||
|
(RemoteLockscreenValidationFragment) getFragmentManager()
|
||||||
|
.findFragmentByTag(FRAGMENT_TAG_REMOTE_LOCKSCREEN_VALIDATION);
|
||||||
|
if (mRemoteLockscreenValidationFragment == null) {
|
||||||
|
mRemoteLockscreenValidationFragment = new RemoteLockscreenValidationFragment();
|
||||||
|
getFragmentManager().beginTransaction().add(mRemoteLockscreenValidationFragment,
|
||||||
|
FRAGMENT_TAG_REMOTE_LOCKSCREEN_VALIDATION).commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,8 +202,10 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
mCancelButton.setOnClickListener(v -> {
|
mCancelButton.setOnClickListener(v -> {
|
||||||
if (hasAlternateButton) {
|
if (hasAlternateButton) {
|
||||||
getActivity().setResult(KeyguardManager.RESULT_ALTERNATE);
|
getActivity().setResult(KeyguardManager.RESULT_ALTERNATE);
|
||||||
}
|
|
||||||
getActivity().finish();
|
getActivity().finish();
|
||||||
|
} else if (mRemoteValidation) {
|
||||||
|
onRemoteLockscreenValidationFailure("Forgot lockscreen credential button pressed.");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
setupForgotButtonIfManagedProfile(view);
|
setupForgotButtonIfManagedProfile(view);
|
||||||
|
|
||||||
@@ -299,17 +309,11 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
if (mRemoteLockscreenValidationClient != null) {
|
if (mRemoteLockscreenValidationClient != null) {
|
||||||
mRemoteLockscreenValidationClient.disconnect();
|
mRemoteLockscreenValidationClient.disconnect();
|
||||||
}
|
}
|
||||||
if (mDeviceCredentialGuess != null) {
|
|
||||||
mDeviceCredentialGuess.zeroize();
|
|
||||||
}
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void authenticationSucceeded();
|
protected abstract void authenticationSucceeded();
|
||||||
|
|
||||||
protected abstract void onRemoteDeviceCredentialValidationResult(
|
|
||||||
RemoteLockscreenValidationResult result);
|
|
||||||
|
|
||||||
public void prepareEnterAnimation() {
|
public void prepareEnterAnimation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,43 +415,33 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void validateGuess(LockscreenCredential credentialGuess) {
|
protected void validateGuess(LockscreenCredential credentialGuess) {
|
||||||
if (mCheckBox.isChecked()) {
|
mRemoteLockscreenValidationFragment.validateLockscreenGuess(
|
||||||
// Keep credential in memory since user wants to set guess as screen lock.
|
mRemoteLockscreenValidationClient, credentialGuess,
|
||||||
mDeviceCredentialGuess = credentialGuess;
|
mRemoteLockscreenValidationSession.getSourcePublicKey(), mCheckBox.isChecked());
|
||||||
} else if (mDeviceCredentialGuess != null) {
|
|
||||||
mDeviceCredentialGuess.zeroize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mRemoteLockscreenValidationClient.validateLockscreenGuess(
|
protected void updateRemoteLockscreenValidationViews() {
|
||||||
encryptDeviceCredentialGuess(credentialGuess.getCredential()),
|
if (!mRemoteValidation || mRemoteLockscreenValidationFragment == null) {
|
||||||
new IRemoteLockscreenValidationCallback.Stub() {
|
return;
|
||||||
@Override
|
|
||||||
public void onSuccess(RemoteLockscreenValidationResult result) {
|
|
||||||
mHandler.post(()->onRemoteDeviceCredentialValidationResult(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
boolean enable = mRemoteLockscreenValidationFragment.isRemoteValidationInProgress();
|
||||||
public void onFailure(String message) {
|
mGlifLayout.setProgressBarShown(enable);
|
||||||
Log.e(TAG, "A failure occurred while trying "
|
mCheckBox.setEnabled(!enable);
|
||||||
+ "to validate lockscreen guess: " + message);
|
mCancelButton.setEnabled(!enable);
|
||||||
mHandler.post(()->getActivity().finish());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] encryptDeviceCredentialGuess(byte[] guess) {
|
/**
|
||||||
try {
|
* Finishes the activity with result code {@link android.app.Activity#RESULT_FIRST_USER}
|
||||||
byte[] encodedPublicKey = mRemoteLockscreenValidationSession.getSourcePublicKey();
|
* after logging the error message.
|
||||||
PublicKey publicKey = SecureBox.decodePublicKey(encodedPublicKey);
|
* @param message Optional message to log.
|
||||||
return SecureBox.encrypt(
|
*/
|
||||||
publicKey,
|
public void onRemoteLockscreenValidationFailure(String message) {
|
||||||
/* sharedSecret= */ null,
|
if (!TextUtils.isEmpty(message)) {
|
||||||
LockPatternUtils.ENCRYPTED_REMOTE_CREDENTIALS_HEADER,
|
Log.w(TAG, message);
|
||||||
guess);
|
|
||||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
|
||||||
Log.w(TAG, "Error encrypting device credential guess. Returning empty byte[].", e);
|
|
||||||
return new byte[0];
|
|
||||||
}
|
}
|
||||||
|
getActivity().setResult(RESULT_FIRST_USER);
|
||||||
|
getActivity().finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void onShowError();
|
protected abstract void onShowError();
|
||||||
|
@@ -71,8 +71,6 @@ import com.android.settings.R;
|
|||||||
import com.android.settingslib.animation.AppearAnimationUtils;
|
import com.android.settingslib.animation.AppearAnimationUtils;
|
||||||
import com.android.settingslib.animation.DisappearAnimationUtils;
|
import com.android.settingslib.animation.DisappearAnimationUtils;
|
||||||
|
|
||||||
import com.google.android.setupdesign.GlifLayout;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||||
@@ -127,7 +125,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
|
|
||||||
public static class ConfirmLockPasswordFragment extends ConfirmDeviceCredentialBaseFragment
|
public static class ConfirmLockPasswordFragment extends ConfirmDeviceCredentialBaseFragment
|
||||||
implements OnClickListener, OnEditorActionListener,
|
implements OnClickListener, OnEditorActionListener,
|
||||||
CredentialCheckResultTracker.Listener, SaveChosenLockWorkerBase.Listener {
|
CredentialCheckResultTracker.Listener, SaveChosenLockWorkerBase.Listener,
|
||||||
|
RemoteLockscreenValidationFragment.Listener {
|
||||||
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
|
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
|
||||||
private ImeAwareEditText mPasswordEntry;
|
private ImeAwareEditText mPasswordEntry;
|
||||||
private TextViewInputDisabler mPasswordEntryInputDisabler;
|
private TextViewInputDisabler mPasswordEntryInputDisabler;
|
||||||
@@ -140,7 +139,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
private AppearAnimationUtils mAppearAnimationUtils;
|
private AppearAnimationUtils mAppearAnimationUtils;
|
||||||
private DisappearAnimationUtils mDisappearAnimationUtils;
|
private DisappearAnimationUtils mDisappearAnimationUtils;
|
||||||
private boolean mIsManagedProfile;
|
private boolean mIsManagedProfile;
|
||||||
private GlifLayout mGlifLayout;
|
|
||||||
private CharSequence mCheckBoxLabel;
|
private CharSequence mCheckBoxLabel;
|
||||||
|
|
||||||
// required constructor for fragments
|
// required constructor for fragments
|
||||||
@@ -255,6 +253,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
? R.string.lockpassword_forgot_password
|
? R.string.lockpassword_forgot_password
|
||||||
: R.string.lockpassword_forgot_pin);
|
: R.string.lockpassword_forgot_pin);
|
||||||
}
|
}
|
||||||
|
updateRemoteLockscreenValidationViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mForgotButton != null) {
|
if (mForgotButton != null) {
|
||||||
@@ -405,6 +404,9 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
mCountdownTimer = null;
|
mCountdownTimer = null;
|
||||||
}
|
}
|
||||||
mCredentialCheckResultTracker.setListener(null);
|
mCredentialCheckResultTracker.setListener(null);
|
||||||
|
if (mRemoteLockscreenValidationFragment != null) {
|
||||||
|
mRemoteLockscreenValidationFragment.setListener(null, /* handler= */ null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -426,6 +428,9 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId));
|
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId));
|
||||||
}
|
}
|
||||||
mCredentialCheckResultTracker.setListener(this);
|
mCredentialCheckResultTracker.setListener(this);
|
||||||
|
if (mRemoteLockscreenValidationFragment != null) {
|
||||||
|
mRemoteLockscreenValidationFragment.setListener(this, mHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -436,13 +441,17 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
private void updatePasswordEntry() {
|
private void updatePasswordEntry() {
|
||||||
final boolean isLockedOut =
|
final boolean isLockedOut =
|
||||||
mLockPatternUtils.getLockoutAttemptDeadline(mEffectiveUserId) != 0;
|
mLockPatternUtils.getLockoutAttemptDeadline(mEffectiveUserId) != 0;
|
||||||
mPasswordEntry.setEnabled(!isLockedOut);
|
final boolean isRemoteLockscreenValidationInProgress =
|
||||||
mPasswordEntryInputDisabler.setInputEnabled(!isLockedOut);
|
mRemoteLockscreenValidationFragment != null
|
||||||
if (isLockedOut) {
|
&& mRemoteLockscreenValidationFragment.isRemoteValidationInProgress();
|
||||||
mImm.hideSoftInputFromWindow(mPasswordEntry.getWindowToken(), 0 /*flags*/);
|
boolean shouldEnableInput = !isLockedOut && !isRemoteLockscreenValidationInProgress;
|
||||||
} else {
|
mPasswordEntry.setEnabled(shouldEnableInput);
|
||||||
|
mPasswordEntryInputDisabler.setInputEnabled(shouldEnableInput);
|
||||||
|
if (shouldEnableInput) {
|
||||||
mPasswordEntry.scheduleShowSoftInput();
|
mPasswordEntry.scheduleShowSoftInput();
|
||||||
mPasswordEntry.requestFocus();
|
mPasswordEntry.requestFocus();
|
||||||
|
} else {
|
||||||
|
mImm.hideSoftInputFromWindow(mPasswordEntry.getWindowToken(), /* flags= */0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,7 +481,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
|
|
||||||
if (mRemoteValidation) {
|
if (mRemoteValidation) {
|
||||||
validateGuess(credential);
|
validateGuess(credential);
|
||||||
mGlifLayout.setProgressBarShown(true);
|
updateRemoteLockscreenValidationViews();
|
||||||
|
updatePasswordEntry();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,14 +614,15 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onRemoteDeviceCredentialValidationResult(
|
public void onRemoteLockscreenValidationResult(
|
||||||
RemoteLockscreenValidationResult result) {
|
RemoteLockscreenValidationResult result) {
|
||||||
switch (result.getResultCode()) {
|
switch (result.getResultCode()) {
|
||||||
case RemoteLockscreenValidationResult.RESULT_GUESS_VALID:
|
case RemoteLockscreenValidationResult.RESULT_GUESS_VALID:
|
||||||
if (mCheckBox.isChecked()) {
|
if (mCheckBox.isChecked() && mRemoteLockscreenValidationFragment
|
||||||
|
.getLockscreenCredential() != null) {
|
||||||
|
Log.i(TAG, "Setting device screen lock to the other device's screen lock.");
|
||||||
ChooseLockPassword.SaveAndFinishWorker saveAndFinishWorker =
|
ChooseLockPassword.SaveAndFinishWorker saveAndFinishWorker =
|
||||||
new ChooseLockPassword.SaveAndFinishWorker();
|
new ChooseLockPassword.SaveAndFinishWorker();
|
||||||
Log.i(TAG, "Setting device screen lock to the other device's screen lock.");
|
|
||||||
getFragmentManager().beginTransaction().add(saveAndFinishWorker, null)
|
getFragmentManager().beginTransaction().add(saveAndFinishWorker, null)
|
||||||
.commit();
|
.commit();
|
||||||
getFragmentManager().executePendingTransactions();
|
getFragmentManager().executePendingTransactions();
|
||||||
@@ -619,14 +630,14 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
saveAndFinishWorker.start(
|
saveAndFinishWorker.start(
|
||||||
mLockPatternUtils,
|
mLockPatternUtils,
|
||||||
/* requestGatekeeperPassword= */ true,
|
/* requestGatekeeperPassword= */ true,
|
||||||
mDeviceCredentialGuess,
|
mRemoteLockscreenValidationFragment.getLockscreenCredential(),
|
||||||
/* currentCredential= */ null,
|
/* currentCredential= */ null,
|
||||||
mEffectiveUserId);
|
mEffectiveUserId);
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
mCredentialCheckResultTracker.setResult(/* matched= */ true, new Intent(),
|
mCredentialCheckResultTracker.setResult(/* matched= */ true, new Intent(),
|
||||||
/* timeoutMs= */ 0, mEffectiveUserId);
|
/* timeoutMs= */ 0, mEffectiveUserId);
|
||||||
break;
|
}
|
||||||
|
return;
|
||||||
case RemoteLockscreenValidationResult.RESULT_GUESS_INVALID:
|
case RemoteLockscreenValidationResult.RESULT_GUESS_INVALID:
|
||||||
mCredentialCheckResultTracker.setResult(/* matched= */ false, new Intent(),
|
mCredentialCheckResultTracker.setResult(/* matched= */ false, new Intent(),
|
||||||
/* timeoutMs= */ 0, mEffectiveUserId);
|
/* timeoutMs= */ 0, mEffectiveUserId);
|
||||||
@@ -636,12 +647,15 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
(int) result.getTimeoutMillis(), mEffectiveUserId);
|
(int) result.getTimeoutMillis(), mEffectiveUserId);
|
||||||
break;
|
break;
|
||||||
case RemoteLockscreenValidationResult.RESULT_NO_REMAINING_ATTEMPTS:
|
case RemoteLockscreenValidationResult.RESULT_NO_REMAINING_ATTEMPTS:
|
||||||
getActivity().finish();
|
|
||||||
break;
|
|
||||||
case RemoteLockscreenValidationResult.RESULT_SESSION_EXPIRED:
|
case RemoteLockscreenValidationResult.RESULT_SESSION_EXPIRED:
|
||||||
getActivity().finish();
|
onRemoteLockscreenValidationFailure(String.format(
|
||||||
|
"Cannot continue remote lockscreen validation. ResultCode=%d",
|
||||||
|
result.getResultCode()));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mGlifLayout.setProgressBarShown(false);
|
updateRemoteLockscreenValidationViews();
|
||||||
|
updatePasswordEntry();
|
||||||
|
mRemoteLockscreenValidationFragment.clearLockscreenCredential();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -701,21 +715,18 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for when the device credential guess used for remote validation was set as the
|
* Callback for when the current device's lockscreen was set to the guess used for
|
||||||
* current device's device credential.
|
* remote lockscreen validation.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
|
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
|
||||||
if (mDeviceCredentialGuess != null) {
|
Log.i(TAG, "Device lockscreen has been set to remote device's lockscreen.");
|
||||||
mDeviceCredentialGuess.zeroize();
|
mRemoteLockscreenValidationFragment.clearLockscreenCredential();
|
||||||
}
|
|
||||||
|
|
||||||
Intent result = new Intent();
|
Intent result = new Intent();
|
||||||
if (mRemoteValidation && containsGatekeeperPasswordHandle(resultData)) {
|
if (mRemoteValidation && containsGatekeeperPasswordHandle(resultData)) {
|
||||||
result.putExtra(EXTRA_KEY_GK_PW_HANDLE, getGatekeeperPasswordHandle(resultData));
|
result.putExtra(EXTRA_KEY_GK_PW_HANDLE, getGatekeeperPasswordHandle(resultData));
|
||||||
}
|
}
|
||||||
|
|
||||||
mGlifLayout.setProgressBarShown(false);
|
|
||||||
mCredentialCheckResultTracker.setResult(/* matched= */ true, result,
|
mCredentialCheckResultTracker.setResult(/* matched= */ true, result,
|
||||||
/* timeoutMs= */ 0, mEffectiveUserId);
|
/* timeoutMs= */ 0, mEffectiveUserId);
|
||||||
}
|
}
|
||||||
|
@@ -59,8 +59,6 @@ import com.android.settingslib.animation.AppearAnimationCreator;
|
|||||||
import com.android.settingslib.animation.AppearAnimationUtils;
|
import com.android.settingslib.animation.AppearAnimationUtils;
|
||||||
import com.android.settingslib.animation.DisappearAnimationUtils;
|
import com.android.settingslib.animation.DisappearAnimationUtils;
|
||||||
|
|
||||||
import com.google.android.setupdesign.GlifLayout;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -97,7 +95,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
|
|
||||||
public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment
|
public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment
|
||||||
implements AppearAnimationCreator<Object>, CredentialCheckResultTracker.Listener,
|
implements AppearAnimationCreator<Object>, CredentialCheckResultTracker.Listener,
|
||||||
SaveChosenLockWorkerBase.Listener {
|
SaveChosenLockWorkerBase.Listener, RemoteLockscreenValidationFragment.Listener {
|
||||||
|
|
||||||
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
|
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
|
||||||
|
|
||||||
@@ -107,7 +105,6 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
private boolean mDisappearing = false;
|
private boolean mDisappearing = false;
|
||||||
private CountDownTimer mCountdownTimer;
|
private CountDownTimer mCountdownTimer;
|
||||||
|
|
||||||
private GlifLayout mGlifLayout;
|
|
||||||
private View mSudContent;
|
private View mSudContent;
|
||||||
|
|
||||||
// caller-supplied text for various prompts
|
// caller-supplied text for various prompts
|
||||||
@@ -239,6 +236,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
if (mCancelButton != null && TextUtils.isEmpty(mAlternateButtonText)) {
|
if (mCancelButton != null && TextUtils.isEmpty(mAlternateButtonText)) {
|
||||||
mCancelButton.setText(R.string.lockpassword_forgot_pattern);
|
mCancelButton.setText(R.string.lockpassword_forgot_pattern);
|
||||||
}
|
}
|
||||||
|
updateRemoteLockscreenValidationViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mForgotButton != null) {
|
if (mForgotButton != null) {
|
||||||
@@ -259,6 +257,9 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
mCountdownTimer.cancel();
|
mCountdownTimer.cancel();
|
||||||
}
|
}
|
||||||
mCredentialCheckResultTracker.setListener(null);
|
mCredentialCheckResultTracker.setListener(null);
|
||||||
|
if (mRemoteLockscreenValidationFragment != null) {
|
||||||
|
mRemoteLockscreenValidationFragment.setListener(null, /* handler= */ null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -281,6 +282,12 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
updateStage(Stage.NeedToUnlock);
|
updateStage(Stage.NeedToUnlock);
|
||||||
}
|
}
|
||||||
mCredentialCheckResultTracker.setListener(this);
|
mCredentialCheckResultTracker.setListener(this);
|
||||||
|
if (mRemoteLockscreenValidationFragment != null) {
|
||||||
|
mRemoteLockscreenValidationFragment.setListener(this, mHandler);
|
||||||
|
if (mRemoteLockscreenValidationFragment.isRemoteValidationInProgress()) {
|
||||||
|
mLockPatternView.setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -502,7 +509,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
|
|
||||||
if (mRemoteValidation) {
|
if (mRemoteValidation) {
|
||||||
validateGuess(credential);
|
validateGuess(credential);
|
||||||
mGlifLayout.setProgressBarShown(true);
|
updateRemoteLockscreenValidationViews();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,11 +624,12 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onRemoteDeviceCredentialValidationResult(
|
public void onRemoteLockscreenValidationResult(
|
||||||
RemoteLockscreenValidationResult result) {
|
RemoteLockscreenValidationResult result) {
|
||||||
switch (result.getResultCode()) {
|
switch (result.getResultCode()) {
|
||||||
case RemoteLockscreenValidationResult.RESULT_GUESS_VALID:
|
case RemoteLockscreenValidationResult.RESULT_GUESS_VALID:
|
||||||
if (mCheckBox.isChecked()) {
|
if (mCheckBox.isChecked() && mRemoteLockscreenValidationFragment
|
||||||
|
.getLockscreenCredential() != null) {
|
||||||
Log.i(TAG, "Setting device screen lock to the other device's screen lock.");
|
Log.i(TAG, "Setting device screen lock to the other device's screen lock.");
|
||||||
ChooseLockPattern.SaveAndFinishWorker saveAndFinishWorker =
|
ChooseLockPattern.SaveAndFinishWorker saveAndFinishWorker =
|
||||||
new ChooseLockPattern.SaveAndFinishWorker();
|
new ChooseLockPattern.SaveAndFinishWorker();
|
||||||
@@ -632,14 +640,14 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
saveAndFinishWorker.start(
|
saveAndFinishWorker.start(
|
||||||
mLockPatternUtils,
|
mLockPatternUtils,
|
||||||
/* requestGatekeeperPassword= */ true,
|
/* requestGatekeeperPassword= */ true,
|
||||||
mDeviceCredentialGuess,
|
mRemoteLockscreenValidationFragment.getLockscreenCredential(),
|
||||||
/* currentCredential= */ null,
|
/* currentCredential= */ null,
|
||||||
mEffectiveUserId);
|
mEffectiveUserId);
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
mCredentialCheckResultTracker.setResult(/* matched= */ true, new Intent(),
|
mCredentialCheckResultTracker.setResult(/* matched= */ true, new Intent(),
|
||||||
/* timeoutMs= */ 0, mEffectiveUserId);
|
/* timeoutMs= */ 0, mEffectiveUserId);
|
||||||
break;
|
}
|
||||||
|
return;
|
||||||
case RemoteLockscreenValidationResult.RESULT_GUESS_INVALID:
|
case RemoteLockscreenValidationResult.RESULT_GUESS_INVALID:
|
||||||
mCredentialCheckResultTracker.setResult(/* matched= */ false, new Intent(),
|
mCredentialCheckResultTracker.setResult(/* matched= */ false, new Intent(),
|
||||||
/* timeoutMs= */ 0, mEffectiveUserId);
|
/* timeoutMs= */ 0, mEffectiveUserId);
|
||||||
@@ -649,12 +657,14 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
(int) result.getTimeoutMillis(), mEffectiveUserId);
|
(int) result.getTimeoutMillis(), mEffectiveUserId);
|
||||||
break;
|
break;
|
||||||
case RemoteLockscreenValidationResult.RESULT_NO_REMAINING_ATTEMPTS:
|
case RemoteLockscreenValidationResult.RESULT_NO_REMAINING_ATTEMPTS:
|
||||||
getActivity().finish();
|
|
||||||
break;
|
|
||||||
case RemoteLockscreenValidationResult.RESULT_SESSION_EXPIRED:
|
case RemoteLockscreenValidationResult.RESULT_SESSION_EXPIRED:
|
||||||
getActivity().finish();
|
onRemoteLockscreenValidationFailure(String.format(
|
||||||
|
"Cannot continue remote lockscreen validation. ResultCode=%d",
|
||||||
|
result.getResultCode()));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mGlifLayout.setProgressBarShown(false);
|
updateRemoteLockscreenValidationViews();
|
||||||
|
mRemoteLockscreenValidationFragment.clearLockscreenCredential();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -728,21 +738,18 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for when the device credential guess used for remote validation was set as the
|
* Callback for when the current device's lockscreen to the guess used for
|
||||||
* current device's device credential.
|
* remote lockscreen validation.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
|
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
|
||||||
if (mDeviceCredentialGuess != null) {
|
Log.i(TAG, "Device lockscreen has been set to remote device's lockscreen.");
|
||||||
mDeviceCredentialGuess.zeroize();
|
mRemoteLockscreenValidationFragment.clearLockscreenCredential();
|
||||||
}
|
|
||||||
|
|
||||||
Intent result = new Intent();
|
Intent result = new Intent();
|
||||||
if (mRemoteValidation && containsGatekeeperPasswordHandle(resultData)) {
|
if (mRemoteValidation && containsGatekeeperPasswordHandle(resultData)) {
|
||||||
result.putExtra(EXTRA_KEY_GK_PW_HANDLE, getGatekeeperPasswordHandle(resultData));
|
result.putExtra(EXTRA_KEY_GK_PW_HANDLE, getGatekeeperPasswordHandle(resultData));
|
||||||
}
|
}
|
||||||
|
|
||||||
mGlifLayout.setProgressBarShown(false);
|
|
||||||
mCredentialCheckResultTracker.setResult(/* matched= */ true, result,
|
mCredentialCheckResultTracker.setResult(/* matched= */ true, result,
|
||||||
/* timeoutMs= */ 0, mEffectiveUserId);
|
/* timeoutMs= */ 0, mEffectiveUserId);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 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 com.android.settings.password;
|
||||||
|
|
||||||
|
import android.app.RemoteLockscreenValidationResult;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.service.remotelockscreenvalidation.IRemoteLockscreenValidationCallback;
|
||||||
|
import android.service.remotelockscreenvalidation.RemoteLockscreenValidationClient;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
|
import com.android.internal.widget.LockscreenCredential;
|
||||||
|
import com.android.security.SecureBox;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fragment used to hold state for remote lockscreen validation.
|
||||||
|
* If the original listener is ever re-created, the new listener must be set again using
|
||||||
|
* {@link #setListener} so that the validation result does not get handled by the old listener.
|
||||||
|
*/
|
||||||
|
public class RemoteLockscreenValidationFragment extends Fragment {
|
||||||
|
|
||||||
|
private static final String TAG = RemoteLockscreenValidationFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private Listener mListener;
|
||||||
|
private Handler mHandler;
|
||||||
|
private boolean mIsInProgress;
|
||||||
|
private RemoteLockscreenValidationResult mResult;
|
||||||
|
private String mErrorMessage;
|
||||||
|
private LockscreenCredential mLockscreenCredential;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setRetainInstance(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
clearLockscreenCredential();
|
||||||
|
if (mResult != null && mErrorMessage != null) {
|
||||||
|
Log.w(TAG, "Unprocessed remote lockscreen validation result");
|
||||||
|
}
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if remote lockscreen guess validation has started or
|
||||||
|
* the validation result has not yet been handled.
|
||||||
|
*/
|
||||||
|
public boolean isRemoteValidationInProgress() {
|
||||||
|
return mIsInProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the listener and handler that will handle the result of remote lockscreen validation.
|
||||||
|
* Unprocessed results or failures will be handled after the listener is set.
|
||||||
|
*/
|
||||||
|
public void setListener(Listener listener, Handler handler) {
|
||||||
|
if (mListener == listener) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mListener = listener;
|
||||||
|
mHandler = handler;
|
||||||
|
|
||||||
|
if (mResult != null) {
|
||||||
|
handleResult();
|
||||||
|
} else if (mErrorMessage != null) {
|
||||||
|
handleFailure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link LockscreenCredential} if it was cached in {@link #validateLockscreenGuess}.
|
||||||
|
*/
|
||||||
|
public LockscreenCredential getLockscreenCredential() {
|
||||||
|
return mLockscreenCredential;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the {@link LockscreenCredential} if it was cached in {@link #validateLockscreenGuess}.
|
||||||
|
*/
|
||||||
|
public void clearLockscreenCredential() {
|
||||||
|
if (mLockscreenCredential != null) {
|
||||||
|
mLockscreenCredential.zeroize();
|
||||||
|
mLockscreenCredential = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the lockscreen guess on the remote device.
|
||||||
|
* @param remoteLockscreenValidationClient the client that should be used to send the guess to
|
||||||
|
* for validation
|
||||||
|
* @param guess the {@link LockscreenCredential} guess that the user entered
|
||||||
|
* @param encryptionKey the key that should be used to encrypt the guess before validation
|
||||||
|
* @param shouldCacheGuess whether to cache to guess so it can be used to set the current
|
||||||
|
* device's lockscreen after validation succeeds.
|
||||||
|
*/
|
||||||
|
public void validateLockscreenGuess(
|
||||||
|
RemoteLockscreenValidationClient remoteLockscreenValidationClient,
|
||||||
|
LockscreenCredential guess, byte[] encryptionKey, boolean shouldCacheGuess) {
|
||||||
|
if (shouldCacheGuess) {
|
||||||
|
mLockscreenCredential = guess;
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteLockscreenValidationClient.validateLockscreenGuess(
|
||||||
|
encryptDeviceCredentialGuess(guess.getCredential(), encryptionKey),
|
||||||
|
new IRemoteLockscreenValidationCallback.Stub() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(RemoteLockscreenValidationResult result) {
|
||||||
|
mResult = result;
|
||||||
|
handleResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(String message) {
|
||||||
|
mErrorMessage = message;
|
||||||
|
handleFailure();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mIsInProgress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] encryptDeviceCredentialGuess(byte[] guess, byte[] encryptionKey) {
|
||||||
|
try {
|
||||||
|
PublicKey publicKey = SecureBox.decodePublicKey(encryptionKey);
|
||||||
|
return SecureBox.encrypt(
|
||||||
|
publicKey,
|
||||||
|
/* sharedSecret= */ null,
|
||||||
|
LockPatternUtils.ENCRYPTED_REMOTE_CREDENTIALS_HEADER,
|
||||||
|
guess);
|
||||||
|
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||||
|
Log.w(TAG, "Error encrypting device credential guess. Returning empty byte[].", e);
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleResult() {
|
||||||
|
if (mHandler != null) {
|
||||||
|
mHandler.post(()-> {
|
||||||
|
if (mListener == null || mResult == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mIsInProgress = false;
|
||||||
|
mListener.onRemoteLockscreenValidationResult(mResult);
|
||||||
|
mResult = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleFailure() {
|
||||||
|
if (mHandler != null) {
|
||||||
|
mHandler.post(()-> {
|
||||||
|
if (mListener == null || mErrorMessage == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mIsInProgress = false;
|
||||||
|
mListener.onRemoteLockscreenValidationFailure(
|
||||||
|
String.format("Remote lockscreen validation failed: %s", mErrorMessage));
|
||||||
|
mErrorMessage = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Listener {
|
||||||
|
void onRemoteLockscreenValidationResult(RemoteLockscreenValidationResult result);
|
||||||
|
void onRemoteLockscreenValidationFailure(String message);
|
||||||
|
}
|
||||||
|
}
|
@@ -197,7 +197,7 @@ public class ConfirmLockPasswordTest {
|
|||||||
verify(mCredentialCheckResultTracker).setResult(
|
verify(mCredentialCheckResultTracker).setResult(
|
||||||
eq(true), any(), eq(0), eq(fragment.mEffectiveUserId));
|
eq(true), any(), eq(0), eq(fragment.mEffectiveUserId));
|
||||||
assertThat(mLockPatternUtils.isSecure(fragment.mEffectiveUserId)).isTrue();
|
assertThat(mLockPatternUtils.isSecure(fragment.mEffectiveUserId)).isTrue();
|
||||||
assertThat(fragment.mDeviceCredentialGuess).isNotNull();
|
assertThat(fragment.mRemoteLockscreenValidationFragment.getLockscreenCredential()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -223,7 +223,7 @@ public class ConfirmLockPasswordTest {
|
|||||||
verify(mCredentialCheckResultTracker).setResult(
|
verify(mCredentialCheckResultTracker).setResult(
|
||||||
eq(true), any(), eq(0), eq(fragment.mEffectiveUserId));
|
eq(true), any(), eq(0), eq(fragment.mEffectiveUserId));
|
||||||
assertThat(mLockPatternUtils.isSecure(fragment.mEffectiveUserId)).isFalse();
|
assertThat(mLockPatternUtils.isSecure(fragment.mEffectiveUserId)).isFalse();
|
||||||
assertThat(fragment.mDeviceCredentialGuess).isNull();
|
assertThat(fragment.mRemoteLockscreenValidationFragment.getLockscreenCredential()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -177,7 +177,7 @@ public class ConfirmLockPatternTest {
|
|||||||
verify(mCredentialCheckResultTracker).setResult(
|
verify(mCredentialCheckResultTracker).setResult(
|
||||||
eq(true), any(), eq(0), eq(fragment.mEffectiveUserId));
|
eq(true), any(), eq(0), eq(fragment.mEffectiveUserId));
|
||||||
assertThat(mLockPatternUtils.isSecure(fragment.mEffectiveUserId)).isTrue();
|
assertThat(mLockPatternUtils.isSecure(fragment.mEffectiveUserId)).isTrue();
|
||||||
assertThat(fragment.mDeviceCredentialGuess).isNotNull();
|
assertThat(fragment.mRemoteLockscreenValidationFragment.getLockscreenCredential()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -203,7 +203,7 @@ public class ConfirmLockPatternTest {
|
|||||||
verify(mCredentialCheckResultTracker).setResult(
|
verify(mCredentialCheckResultTracker).setResult(
|
||||||
eq(true), any(), eq(0), eq(fragment.mEffectiveUserId));
|
eq(true), any(), eq(0), eq(fragment.mEffectiveUserId));
|
||||||
assertThat(mLockPatternUtils.isSecure(fragment.mEffectiveUserId)).isFalse();
|
assertThat(mLockPatternUtils.isSecure(fragment.mEffectiveUserId)).isFalse();
|
||||||
assertThat(fragment.mDeviceCredentialGuess).isNull();
|
assertThat(fragment.mRemoteLockscreenValidationFragment.getLockscreenCredential()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Reference in New Issue
Block a user