Merge "Call reportFailedPasswordAttempt from Work Challenge" into nyc-dev

This commit is contained in:
Clara Bayarri
2016-02-18 11:16:26 +00:00
committed by Android (Google) Code Review
5 changed files with 162 additions and 43 deletions

View File

@@ -1130,6 +1130,21 @@
<!-- Title shown on security settings to allow the user to change their lockscreen password [CHAR LIMIT=22]-->
<string name="unlock_change_lock_password_title">Change unlock password</string>
<!-- Message shown when the user incorrectly enters their lock and it counts towards the max attempts before wiping the work profile. -->
<string name="lock_profile_wipe_attempts">Try again. Attempt <xliff:g id="current_attempts">%1$d</xliff:g> of <xliff:g id="total_attempts">%2$d</xliff:g>.</string>
<!-- Title of a dialog shown when the user only has one attempt left to provide the lock before the work profile is wiped. -->
<string name="lock_profile_wipe_warning_title">Last try</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the work pattern before the work profile is wiped. -->
<string name="lock_profile_wipe_warning_content_pattern">If you enter an incorrect work pattern on this attempt, your work profile and associated data will be removed from this device.</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the work PIN before the work profile is wiped. -->
<string name="lock_profile_wipe_warning_content_pin">If you enter an incorrect work PIN on this attempt, your work profile and associated data will be removed from this device.</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the work password before the work profile is wiped. -->
<string name="lock_profile_wipe_warning_content_password">If you enter an incorrect work password on this attempt, your work profile and associated data will be removed from this device.</string>
<!-- Content of the dialog shown when the user has failed to provide the work lock too many times and the work profile is wiped. -->
<string name="lock_profile_wipe_content">Too many incorrect attempts. Your work profile and associated data will be removed from this device.</string>
<!-- Button label to dismiss the dialog telling the user the work profile has been wiped. [CHAR LIMIT=40] -->
<string name="lock_profile_wipe_dismiss">Dismiss</string>
<!-- Hint shown in dialog screen when password is too short -->
<string name="lockpassword_password_too_short">Password must be at least %d characters</string>
<!-- Hint shown in dialog screen when PIN is too short -->

View File

@@ -20,10 +20,13 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.AlertDialog;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentSender;
import android.graphics.Point;
@@ -31,7 +34,9 @@ import android.graphics.PorterDuff;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.view.View;
import android.view.ViewGroup;
@@ -40,6 +45,7 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.fingerprint.FingerprintUiHelper;
/**
@@ -65,6 +71,9 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
protected Button mCancelButton;
protected ImageView mFingerprintIcon;
protected int mEffectiveUserId;
protected LockPatternUtils mLockPatternUtils;
protected TextView mErrorTextView;
protected final Handler mHandler = new Handler();
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -74,6 +83,7 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
// Only take this argument into account if it belongs to the current profile.
Intent intent = getActivity().getIntent();
mEffectiveUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras());
mLockPatternUtils = new LockPatternUtils(getActivity());
}
@Override
@@ -109,6 +119,10 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
if (mAllowFpAuthentication) {
mFingerprintHelper.startListening();
}
if (isProfileChallenge()) {
updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
mEffectiveUserId));
}
}
protected void setAccessibilityTitle(CharSequence suplementalText) {
@@ -200,4 +214,87 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
screenSize.y));
}
}
protected boolean isProfileChallenge() {
return UserHandle.myUserId() != mEffectiveUserId;
}
protected void reportSuccessfullAttempt() {
if (isProfileChallenge()) {
mLockPatternUtils.reportSuccessfulPasswordAttempt(mEffectiveUserId);
}
}
protected void reportFailedAttempt() {
if (isProfileChallenge()) {
// + 1 for this attempt.
updateErrorMessage(
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId) + 1);
mLockPatternUtils.reportFailedPasswordAttempt(mEffectiveUserId);
}
}
protected void updateErrorMessage(int numAttempts) {
final int maxAttempts =
mLockPatternUtils.getMaximumFailedPasswordsForWipe(mEffectiveUserId);
if (maxAttempts > 0 && numAttempts > 0) {
int remainingAttempts = maxAttempts - numAttempts;
if (remainingAttempts == 1) {
// Last try
final String title = getActivity().getString(
R.string.lock_profile_wipe_warning_title);
final String message = getActivity().getString(getLastTryErrorMessage());
showDialog(title, message, android.R.string.ok, false /* dismiss */);
} else if (remainingAttempts <= 0) {
// Profile is wiped
final String message = getActivity().getString(R.string.lock_profile_wipe_content);
showDialog(null, message, R.string.lock_profile_wipe_dismiss, true /* dismiss */);
}
if (mErrorTextView != null) {
final String message = getActivity().getString(R.string.lock_profile_wipe_attempts,
numAttempts, maxAttempts);
showError(message, 0);
}
}
}
protected abstract int getLastTryErrorMessage();
private final Runnable mResetErrorRunnable = new Runnable() {
@Override
public void run() {
mErrorTextView.setText("");
}
};
protected void showError(CharSequence msg, long timeout) {
mErrorTextView.setText(msg);
onShowError();
mHandler.removeCallbacks(mResetErrorRunnable);
if (timeout != 0) {
mHandler.postDelayed(mResetErrorRunnable, timeout);
}
}
protected abstract void onShowError();
protected void showError(int msg, long timeout) {
showError(getText(msg), timeout);
}
private void showDialog(String title, String message, int buttonString, final boolean dismiss) {
final AlertDialog dialog = new AlertDialog.Builder(getActivity())
.setTitle(title)
.setMessage(message)
.setPositiveButton(buttonString, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (dismiss) {
getActivity().finish();
}
}
})
.create();
dialog.show();
}
}

View File

@@ -20,11 +20,9 @@ import android.app.Fragment;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.SystemClock;
import android.os.UserManager;
import android.os.storage.StorageManager;
@@ -84,14 +82,11 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
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 CountDownTimer mCountdownTimer;
private boolean mIsAlpha;
private InputMethodManager mImm;
@@ -108,7 +103,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLockPatternUtils = new LockPatternUtils(getActivity());
}
@Override
@@ -193,6 +187,12 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
: R.string.lockpassword_invalid_pin;
}
@Override
protected int getLastTryErrorMessage() {
return mIsAlpha ? R.string.lock_profile_wipe_warning_content_password
: R.string.lock_profile_wipe_warning_content_pin;
}
@Override
public void prepareEnterAnimation() {
super.prepareEnterAnimation();
@@ -406,9 +406,12 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
}
private void onPasswordChecked(boolean matched, Intent intent, int timeoutMs,
int effectiveUserId) {
int effectiveUserId, boolean newResult) {
mPasswordEntryInputDisabler.setInputEnabled(true);
if (matched) {
if (newResult) {
reportSuccessfullAttempt();
}
startDisappearAnimation(intent);
checkForPendingIntent();
} else {
@@ -417,15 +420,23 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
effectiveUserId, timeoutMs);
handleAttemptLockout(deadline);
} else {
showError(getErrorMessage());
showError(getErrorMessage(), ERROR_MESSAGE_TIMEOUT);
}
if (newResult) {
reportFailedAttempt();
}
}
}
@Override
public void onCredentialChecked(boolean matched, Intent intent, int timeoutMs,
int effectiveUserId) {
onPasswordChecked(matched, intent, timeoutMs, effectiveUserId);
int effectiveUserId, boolean newResult) {
onPasswordChecked(matched, intent, timeoutMs, effectiveUserId, newResult);
}
@Override
protected void onShowError() {
mPasswordEntry.setText(null);
}
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
@@ -447,6 +458,10 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
public void onFinish() {
resetState();
mErrorTextView.setText("");
if (isProfileChallenge()) {
updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
mEffectiveUserId));
}
}
}.start();
}
@@ -464,29 +479,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
}
}
private void showError(int msg) {
showError(msg, ERROR_MESSAGE_TIMEOUT);
}
private final Runnable mResetErrorRunnable = new Runnable() {
public void run() {
mErrorTextView.setText("");
}
};
private void showError(CharSequence msg, long timeout) {
mErrorTextView.setText(msg);
mPasswordEntry.setText(null);
mHandler.removeCallbacks(mResetErrorRunnable);
if (timeout != 0) {
mHandler.postDelayed(mResetErrorRunnable, timeout);
}
}
private void showError(int msg, long timeout) {
showError(getText(msg), timeout);
}
// {@link OnEditorActionListener} methods.
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
// Check if this was the result of hitting the enter or "done" key

View File

@@ -18,7 +18,6 @@ package com.android.settings;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
@@ -85,7 +84,6 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
private LockPatternView mLockPatternView;
private LockPatternUtils mLockPatternUtils;
private AsyncTask<?, ?, ?> mPendingLockCheck;
private CredentialCheckResultTracker mCredentialCheckResultTracker;
private boolean mDisappearing = false;
@@ -93,7 +91,6 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
private TextView mHeaderTextView;
private TextView mDetailsTextView;
private TextView mErrorTextView;
private View mLeftSpacerLandscape;
private View mRightSpacerLandscape;
@@ -112,7 +109,6 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLockPatternUtils = new LockPatternUtils(getActivity());
}
@Override
@@ -220,6 +216,10 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
mCredentialCheckResultTracker.setListener(this);
}
@Override
protected void onShowError() {
}
@Override
public void prepareEnterAnimation() {
super.prepareEnterAnimation();
@@ -284,6 +284,10 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
R.string.lockpassword_confirm_your_pattern_generic_profile);
}
mErrorTextView.setText("");
if (isProfileChallenge()) {
updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
mEffectiveUserId));
}
mLockPatternView.setEnabled(true);
mLockPatternView.enableInput();
@@ -470,9 +474,12 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
};
private void onPatternChecked(boolean matched, Intent intent, int timeoutMs,
int effectiveUserId) {
int effectiveUserId, boolean newResult) {
mLockPatternView.setEnabled(true);
if (matched) {
if (newResult) {
reportSuccessfullAttempt();
}
startDisappearAnimation(intent);
checkForPendingIntent();
} else {
@@ -484,13 +491,21 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
updateStage(Stage.NeedToUnlockWrong);
postClearPatternRunnable();
}
if (newResult) {
reportFailedAttempt();
}
}
}
@Override
public void onCredentialChecked(boolean matched, Intent intent, int timeoutMs,
int effectiveUserId) {
onPatternChecked(matched, intent, timeoutMs, effectiveUserId);
int effectiveUserId, boolean newResult) {
onPatternChecked(matched, intent, timeoutMs, effectiveUserId, newResult);
}
@Override
protected int getLastTryErrorMessage() {
return R.string.lock_profile_wipe_warning_content_pattern;
}
private void handleAttemptLockout(long elapsedRealtimeDeadline) {

View File

@@ -47,7 +47,7 @@ public class CredentialCheckResultTracker extends Fragment {
mListener = listener;
if (mListener != null && mHasResult) {
mListener.onCredentialChecked(mResultMatched, mResultData, mResultTimeoutMs,
mResultEffectiveUserId);
mResultEffectiveUserId, false /* newResult */);
}
}
@@ -60,7 +60,7 @@ public class CredentialCheckResultTracker extends Fragment {
mHasResult = true;
if (mListener != null) {
mListener.onCredentialChecked(mResultMatched, mResultData, mResultTimeoutMs,
mResultEffectiveUserId);
mResultEffectiveUserId, true /* newResult */);
}
}
@@ -74,6 +74,6 @@ public class CredentialCheckResultTracker extends Fragment {
interface Listener {
public void onCredentialChecked(boolean matched, Intent intent, int timeoutMs,
int effectiveUserId);
int effectiveUserId, boolean newResult);
}
}