Merge "Fix races in ConfirmPassword/Pattern" into mnc-dr-dev
This commit is contained in:
@@ -16,10 +16,8 @@
|
|||||||
|
|
||||||
package com.android.settings;
|
package com.android.settings;
|
||||||
|
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import com.android.internal.logging.MetricsLogger;
|
import com.android.internal.logging.MetricsLogger;
|
||||||
import com.android.internal.util.ArrayUtils;
|
|
||||||
import com.android.internal.widget.LockPatternChecker;
|
import com.android.internal.widget.LockPatternChecker;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.internal.widget.TextViewInputDisabler;
|
import com.android.internal.widget.TextViewInputDisabler;
|
||||||
@@ -78,19 +76,20 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class ConfirmLockPasswordFragment extends ConfirmDeviceCredentialBaseFragment
|
public static class ConfirmLockPasswordFragment extends ConfirmDeviceCredentialBaseFragment
|
||||||
implements OnClickListener, OnEditorActionListener {
|
implements OnClickListener, OnEditorActionListener,
|
||||||
private static final String KEY_NUM_WRONG_CONFIRM_ATTEMPTS
|
CredentialCheckResultTracker.Listener {
|
||||||
= "confirm_lock_password_fragment.key_num_wrong_confirm_attempts";
|
|
||||||
private static final long ERROR_MESSAGE_TIMEOUT = 3000;
|
private static final long ERROR_MESSAGE_TIMEOUT = 3000;
|
||||||
|
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
|
||||||
private TextView mPasswordEntry;
|
private TextView mPasswordEntry;
|
||||||
private TextViewInputDisabler mPasswordEntryInputDisabler;
|
private TextViewInputDisabler mPasswordEntryInputDisabler;
|
||||||
private LockPatternUtils mLockPatternUtils;
|
private LockPatternUtils mLockPatternUtils;
|
||||||
private AsyncTask<?, ?, ?> mPendingLockCheck;
|
private AsyncTask<?, ?, ?> mPendingLockCheck;
|
||||||
|
private CredentialCheckResultTracker mCredentialCheckResultTracker;
|
||||||
|
private boolean mDisappearing = false;
|
||||||
private TextView mHeaderTextView;
|
private TextView mHeaderTextView;
|
||||||
private TextView mDetailsTextView;
|
private TextView mDetailsTextView;
|
||||||
private TextView mErrorTextView;
|
private TextView mErrorTextView;
|
||||||
private Handler mHandler = new Handler();
|
private Handler mHandler = new Handler();
|
||||||
private int mNumWrongConfirmAttempts;
|
|
||||||
private CountDownTimer mCountdownTimer;
|
private CountDownTimer mCountdownTimer;
|
||||||
private boolean mIsAlpha;
|
private boolean mIsAlpha;
|
||||||
private InputMethodManager mImm;
|
private InputMethodManager mImm;
|
||||||
@@ -110,11 +109,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
mLockPatternUtils = new LockPatternUtils(getActivity());
|
mLockPatternUtils = new LockPatternUtils(getActivity());
|
||||||
mEffectiveUserId = Utils.getEffectiveUserId(getActivity());
|
mEffectiveUserId = Utils.getEffectiveUserId(getActivity());
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
|
||||||
mNumWrongConfirmAttempts = savedInstanceState.getInt(
|
|
||||||
KEY_NUM_WRONG_CONFIRM_ATTEMPTS, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -165,6 +159,15 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
0.5f /* delayScale */, AnimationUtils.loadInterpolator(
|
0.5f /* delayScale */, AnimationUtils.loadInterpolator(
|
||||||
getContext(), android.R.interpolator.fast_out_linear_in));
|
getContext(), android.R.interpolator.fast_out_linear_in));
|
||||||
setAccessibilityTitle(mHeaderTextView.getText());
|
setAccessibilityTitle(mHeaderTextView.getText());
|
||||||
|
|
||||||
|
mCredentialCheckResultTracker = (CredentialCheckResultTracker) getFragmentManager()
|
||||||
|
.findFragmentByTag(FRAGMENT_TAG_CHECK_LOCK_RESULT);
|
||||||
|
if (mCredentialCheckResultTracker == null) {
|
||||||
|
mCredentialCheckResultTracker = new CredentialCheckResultTracker();
|
||||||
|
getFragmentManager().beginTransaction().add(mCredentialCheckResultTracker,
|
||||||
|
FRAGMENT_TAG_CHECK_LOCK_RESULT).commit();
|
||||||
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,10 +230,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
mCountdownTimer.cancel();
|
mCountdownTimer.cancel();
|
||||||
mCountdownTimer = null;
|
mCountdownTimer = null;
|
||||||
}
|
}
|
||||||
if (mPendingLockCheck != null) {
|
mCredentialCheckResultTracker.setListener(null);
|
||||||
mPendingLockCheck.cancel(false);
|
|
||||||
mPendingLockCheck = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -243,21 +243,17 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
super.onResume();
|
super.onResume();
|
||||||
long deadline = mLockPatternUtils.getLockoutAttemptDeadline(mEffectiveUserId);
|
long deadline = mLockPatternUtils.getLockoutAttemptDeadline(mEffectiveUserId);
|
||||||
if (deadline != 0) {
|
if (deadline != 0) {
|
||||||
|
mCredentialCheckResultTracker.clearResult();
|
||||||
handleAttemptLockout(deadline);
|
handleAttemptLockout(deadline);
|
||||||
} else {
|
} else {
|
||||||
resetState();
|
resetState();
|
||||||
}
|
}
|
||||||
}
|
mCredentialCheckResultTracker.setListener(this);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
outState.putInt(KEY_NUM_WRONG_CONFIRM_ATTEMPTS, mNumWrongConfirmAttempts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void authenticationSucceeded() {
|
protected void authenticationSucceeded() {
|
||||||
startDisappearAnimation(new Intent());
|
mCredentialCheckResultTracker.setResult(true, new Intent(), 0, mEffectiveUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -298,11 +294,12 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleNext() {
|
private void handleNext() {
|
||||||
mPasswordEntryInputDisabler.setInputEnabled(false);
|
if (mPendingLockCheck != null || mDisappearing) {
|
||||||
if (mPendingLockCheck != null) {
|
return;
|
||||||
mPendingLockCheck.cancel(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mPasswordEntryInputDisabler.setInputEnabled(false);
|
||||||
|
|
||||||
final String pin = mPasswordEntry.getText().toString();
|
final String pin = mPasswordEntry.getText().toString();
|
||||||
final boolean verifyChallenge = getActivity().getIntent().getBooleanExtra(
|
final boolean verifyChallenge = getActivity().getIntent().getBooleanExtra(
|
||||||
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
|
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
|
||||||
@@ -317,7 +314,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onPasswordChecked(false, intent, 0, mEffectiveUserId);
|
mCredentialCheckResultTracker.setResult(false, intent, 0, mEffectiveUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInternalActivity() {
|
private boolean isInternalActivity() {
|
||||||
@@ -344,7 +341,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN,
|
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN,
|
||||||
token);
|
token);
|
||||||
}
|
}
|
||||||
onPasswordChecked(matched, intent, timeoutMs, localEffectiveUserId);
|
mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs,
|
||||||
|
localEffectiveUserId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -366,16 +364,27 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
intent.putExtra(
|
intent.putExtra(
|
||||||
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pin);
|
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pin);
|
||||||
}
|
}
|
||||||
onPasswordChecked(matched, intent, timeoutMs, localEffectiveUserId);
|
mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs,
|
||||||
|
localEffectiveUserId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startDisappearAnimation(final Intent intent) {
|
private void startDisappearAnimation(final Intent intent) {
|
||||||
|
if (mDisappearing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mDisappearing = true;
|
||||||
|
|
||||||
if (getActivity().getThemeResId() == R.style.Theme_ConfirmDeviceCredentialsDark) {
|
if (getActivity().getThemeResId() == R.style.Theme_ConfirmDeviceCredentialsDark) {
|
||||||
mDisappearAnimationUtils.startAnimation(getActiveViews(), new Runnable() {
|
mDisappearAnimationUtils.startAnimation(getActiveViews(), new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
// Bail if there is no active activity.
|
||||||
|
if (getActivity() == null || getActivity().isFinishing()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
getActivity().setResult(RESULT_OK, intent);
|
getActivity().setResult(RESULT_OK, intent);
|
||||||
getActivity().finish();
|
getActivity().finish();
|
||||||
getActivity().overridePendingTransition(
|
getActivity().overridePendingTransition(
|
||||||
@@ -405,6 +414,12 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCredentialChecked(boolean matched, Intent intent, int timeoutMs,
|
||||||
|
int effectiveUserId) {
|
||||||
|
onPasswordChecked(matched, intent, timeoutMs, effectiveUserId);
|
||||||
|
}
|
||||||
|
|
||||||
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
|
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
|
||||||
long elapsedRealtime = SystemClock.elapsedRealtime();
|
long elapsedRealtime = SystemClock.elapsedRealtime();
|
||||||
mPasswordEntry.setEnabled(false);
|
mPasswordEntry.setEnabled(false);
|
||||||
@@ -424,7 +439,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
public void onFinish() {
|
public void onFinish() {
|
||||||
resetState();
|
resetState();
|
||||||
mErrorTextView.setText("");
|
mErrorTextView.setText("");
|
||||||
mNumWrongConfirmAttempts = 0;
|
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,6 @@ import android.os.CountDownTimer;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.os.storage.StorageManager;
|
import android.os.storage.StorageManager;
|
||||||
import android.view.animation.AnimationUtils;
|
import android.view.animation.AnimationUtils;
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
@@ -76,17 +75,18 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment
|
public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment
|
||||||
implements AppearAnimationCreator<Object> {
|
implements AppearAnimationCreator<Object>, CredentialCheckResultTracker.Listener {
|
||||||
|
|
||||||
// how long we wait to clear a wrong pattern
|
// how long we wait to clear a wrong pattern
|
||||||
private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
|
private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
|
||||||
|
|
||||||
private static final String KEY_NUM_WRONG_ATTEMPTS = "num_wrong_attempts";
|
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
|
||||||
|
|
||||||
private LockPatternView mLockPatternView;
|
private LockPatternView mLockPatternView;
|
||||||
private LockPatternUtils mLockPatternUtils;
|
private LockPatternUtils mLockPatternUtils;
|
||||||
private AsyncTask<?, ?, ?> mPendingLockCheck;
|
private AsyncTask<?, ?, ?> mPendingLockCheck;
|
||||||
private int mNumWrongConfirmAttempts;
|
private CredentialCheckResultTracker mCredentialCheckResultTracker;
|
||||||
|
private boolean mDisappearing = false;
|
||||||
private CountDownTimer mCountdownTimer;
|
private CountDownTimer mCountdownTimer;
|
||||||
|
|
||||||
private TextView mHeaderTextView;
|
private TextView mHeaderTextView;
|
||||||
@@ -148,9 +148,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
mLockPatternView.setOnPatternListener(mConfirmExistingLockPatternListener);
|
mLockPatternView.setOnPatternListener(mConfirmExistingLockPatternListener);
|
||||||
updateStage(Stage.NeedToUnlock);
|
updateStage(Stage.NeedToUnlock);
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState == null) {
|
||||||
mNumWrongConfirmAttempts = savedInstanceState.getInt(KEY_NUM_WRONG_ATTEMPTS);
|
|
||||||
} else {
|
|
||||||
// on first launch, if no lock pattern is set, then finish with
|
// on first launch, if no lock pattern is set, then finish with
|
||||||
// success (don't want user to get stuck confirming something that
|
// success (don't want user to get stuck confirming something that
|
||||||
// doesn't exist).
|
// doesn't exist).
|
||||||
@@ -174,13 +172,21 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
setAccessibilityTitle(mHeaderTextView.getText());
|
setAccessibilityTitle(mHeaderTextView.getText());
|
||||||
|
|
||||||
|
mCredentialCheckResultTracker = (CredentialCheckResultTracker) getFragmentManager()
|
||||||
|
.findFragmentByTag(FRAGMENT_TAG_CHECK_LOCK_RESULT);
|
||||||
|
if (mCredentialCheckResultTracker == null) {
|
||||||
|
mCredentialCheckResultTracker = new CredentialCheckResultTracker();
|
||||||
|
getFragmentManager().beginTransaction().add(mCredentialCheckResultTracker,
|
||||||
|
FRAGMENT_TAG_CHECK_LOCK_RESULT).commit();
|
||||||
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
// deliberately not calling super since we are managing this in full
|
// deliberately not calling super since we are managing this in full
|
||||||
outState.putInt(KEY_NUM_WRONG_ATTEMPTS, mNumWrongConfirmAttempts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -190,10 +196,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
if (mCountdownTimer != null) {
|
if (mCountdownTimer != null) {
|
||||||
mCountdownTimer.cancel();
|
mCountdownTimer.cancel();
|
||||||
}
|
}
|
||||||
if (mPendingLockCheck != null) {
|
mCredentialCheckResultTracker.setListener(null);
|
||||||
mPendingLockCheck.cancel(false);
|
|
||||||
mPendingLockCheck = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -208,13 +211,14 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
// if the user is currently locked out, enforce it.
|
// if the user is currently locked out, enforce it.
|
||||||
long deadline = mLockPatternUtils.getLockoutAttemptDeadline(mEffectiveUserId);
|
long deadline = mLockPatternUtils.getLockoutAttemptDeadline(mEffectiveUserId);
|
||||||
if (deadline != 0) {
|
if (deadline != 0) {
|
||||||
|
mCredentialCheckResultTracker.clearResult();
|
||||||
handleAttemptLockout(deadline);
|
handleAttemptLockout(deadline);
|
||||||
} else if (!mLockPatternView.isEnabled()) {
|
} else if (!mLockPatternView.isEnabled()) {
|
||||||
// The deadline has passed, but the timer was cancelled. Or the pending lock
|
// The deadline has passed, but the timer was cancelled. Or the pending lock
|
||||||
// check was cancelled. Need to clean up.
|
// check was cancelled. Need to clean up.
|
||||||
mNumWrongConfirmAttempts = 0;
|
|
||||||
updateStage(Stage.NeedToUnlock);
|
updateStage(Stage.NeedToUnlock);
|
||||||
}
|
}
|
||||||
|
mCredentialCheckResultTracker.setListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -317,16 +321,26 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void authenticationSucceeded() {
|
protected void authenticationSucceeded() {
|
||||||
startDisappearAnimation(new Intent());
|
mCredentialCheckResultTracker.setResult(true, new Intent(), 0, mEffectiveUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startDisappearAnimation(final Intent intent) {
|
private void startDisappearAnimation(final Intent intent) {
|
||||||
|
if (mDisappearing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mDisappearing = true;
|
||||||
|
|
||||||
if (getActivity().getThemeResId() == R.style.Theme_ConfirmDeviceCredentialsDark) {
|
if (getActivity().getThemeResId() == R.style.Theme_ConfirmDeviceCredentialsDark) {
|
||||||
mLockPatternView.clearPattern();
|
mLockPatternView.clearPattern();
|
||||||
mDisappearAnimationUtils.startAnimation2d(getActiveViews(),
|
mDisappearAnimationUtils.startAnimation2d(getActiveViews(),
|
||||||
new Runnable() {
|
new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
// Bail if there is no active activity.
|
||||||
|
if (getActivity() == null || getActivity().isFinishing()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
getActivity().setResult(RESULT_OK, intent);
|
getActivity().setResult(RESULT_OK, intent);
|
||||||
getActivity().finish();
|
getActivity().finish();
|
||||||
getActivity().overridePendingTransition(
|
getActivity().overridePendingTransition(
|
||||||
@@ -370,11 +384,12 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onPatternDetected(List<LockPatternView.Cell> pattern) {
|
public void onPatternDetected(List<LockPatternView.Cell> pattern) {
|
||||||
mLockPatternView.setEnabled(false);
|
if (mPendingLockCheck != null || mDisappearing) {
|
||||||
if (mPendingLockCheck != null) {
|
return;
|
||||||
mPendingLockCheck.cancel(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mLockPatternView.setEnabled(false);
|
||||||
|
|
||||||
final boolean verifyChallenge = getActivity().getIntent().getBooleanExtra(
|
final boolean verifyChallenge = getActivity().getIntent().getBooleanExtra(
|
||||||
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
|
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
@@ -388,7 +403,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onPatternChecked(pattern, false, intent, 0, mEffectiveUserId);
|
mCredentialCheckResultTracker.setResult(false, intent, 0, mEffectiveUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInternalActivity() {
|
private boolean isInternalActivity() {
|
||||||
@@ -416,8 +431,8 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN,
|
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN,
|
||||||
token);
|
token);
|
||||||
}
|
}
|
||||||
onPatternChecked(pattern,
|
mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs,
|
||||||
matched, intent, timeoutMs, localEffectiveUserId);
|
localEffectiveUserId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -425,7 +440,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
private void startCheckPattern(final List<LockPatternView.Cell> pattern,
|
private void startCheckPattern(final List<LockPatternView.Cell> pattern,
|
||||||
final Intent intent) {
|
final Intent intent) {
|
||||||
if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
|
if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
|
||||||
onPatternChecked(pattern, false, intent, 0, mEffectiveUserId);
|
mCredentialCheckResultTracker.setResult(false, intent, 0, mEffectiveUserId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,29 +459,35 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
|
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
|
||||||
LockPatternUtils.patternToString(pattern));
|
LockPatternUtils.patternToString(pattern));
|
||||||
}
|
}
|
||||||
onPatternChecked(pattern, matched, intent, timeoutMs,
|
mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs,
|
||||||
localEffectiveUserId);
|
localEffectiveUserId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private void onPatternChecked(List<LockPatternView.Cell> pattern,
|
private void onPatternChecked(boolean matched, Intent intent, int timeoutMs,
|
||||||
boolean matched, Intent intent, int timeoutMs, int effectiveUserId) {
|
int effectiveUserId) {
|
||||||
mLockPatternView.setEnabled(true);
|
mLockPatternView.setEnabled(true);
|
||||||
if (matched) {
|
if (matched) {
|
||||||
startDisappearAnimation(intent);
|
startDisappearAnimation(intent);
|
||||||
|
} else {
|
||||||
|
if (timeoutMs > 0) {
|
||||||
|
long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
|
||||||
|
effectiveUserId, timeoutMs);
|
||||||
|
handleAttemptLockout(deadline);
|
||||||
} else {
|
} else {
|
||||||
if (timeoutMs > 0) {
|
updateStage(Stage.NeedToUnlockWrong);
|
||||||
long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
|
postClearPatternRunnable();
|
||||||
effectiveUserId, timeoutMs);
|
|
||||||
handleAttemptLockout(deadline);
|
|
||||||
} else {
|
|
||||||
updateStage(Stage.NeedToUnlockWrong);
|
|
||||||
postClearPatternRunnable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCredentialChecked(boolean matched, Intent intent, int timeoutMs,
|
||||||
|
int effectiveUserId) {
|
||||||
|
onPatternChecked(matched, intent, timeoutMs, effectiveUserId);
|
||||||
|
}
|
||||||
|
|
||||||
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
|
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
|
||||||
updateStage(Stage.LockedOut);
|
updateStage(Stage.LockedOut);
|
||||||
@@ -485,7 +506,6 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFinish() {
|
public void onFinish() {
|
||||||
mNumWrongConfirmAttempts = 0;
|
|
||||||
updateStage(Stage.NeedToUnlock);
|
updateStage(Stage.NeedToUnlock);
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
|
79
src/com/android/settings/CredentialCheckResultTracker.java
Normal file
79
src/com/android/settings/CredentialCheckResultTracker.java
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 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;
|
||||||
|
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An invisible retained fragment to track lock check result.
|
||||||
|
*/
|
||||||
|
class CredentialCheckResultTracker extends Fragment {
|
||||||
|
|
||||||
|
private Listener mListener;
|
||||||
|
private boolean mHasResult = false;
|
||||||
|
|
||||||
|
private boolean mResultMatched;
|
||||||
|
private Intent mResultData;
|
||||||
|
private int mResultTimeoutMs;
|
||||||
|
private int mResultEffectiveUserId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setRetainInstance(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListener(Listener listener) {
|
||||||
|
if (mListener == listener) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mListener = listener;
|
||||||
|
if (mListener != null && mHasResult) {
|
||||||
|
mListener.onCredentialChecked(mResultMatched, mResultData, mResultTimeoutMs,
|
||||||
|
mResultEffectiveUserId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResult(boolean matched, Intent intent, int timeoutMs, int effectiveUserId) {
|
||||||
|
mResultMatched = matched;
|
||||||
|
mResultData = intent;
|
||||||
|
mResultTimeoutMs = timeoutMs;
|
||||||
|
mResultEffectiveUserId = effectiveUserId;
|
||||||
|
|
||||||
|
mHasResult = true;
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onCredentialChecked(mResultMatched, mResultData, mResultTimeoutMs,
|
||||||
|
mResultEffectiveUserId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearResult() {
|
||||||
|
mHasResult = false;
|
||||||
|
mResultMatched = false;
|
||||||
|
mResultData = null;
|
||||||
|
mResultTimeoutMs = 0;
|
||||||
|
mResultEffectiveUserId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Listener {
|
||||||
|
public void onCredentialChecked(boolean matched, Intent intent, int timeoutMs,
|
||||||
|
int effectiveUserId);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user