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