Update confirm device credentials to spec, add fingerprint
- New strings in the screen. - New layout/style. - Clean up internal API's around it. - Add fingerprint support if launched from externally - Separate theme if launched from externally - If launched from above Keyguard, use SHOW_WHEN_LOCKED flag Change-Id: Icdf9bf9e0506841f24e8aab5f0f1d1f4b688951f
This commit is contained in:
@@ -145,7 +145,8 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
} else if (!mWaitingForConfirmation) {
|
||||
ChooseLockSettingsHelper helper =
|
||||
new ChooseLockSettingsHelper(this.getActivity(), this);
|
||||
if (!helper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST, null, null)) {
|
||||
if (!helper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST,
|
||||
getString(R.string.unlock_set_unlock_launch_picker_title))) {
|
||||
mPasswordConfirmed = true; // no password set, so no need to confirm
|
||||
updatePreferencesOrFinish();
|
||||
} else {
|
||||
|
@@ -243,7 +243,7 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
updateStage(Stage.Introduction);
|
||||
if (confirmCredentials) {
|
||||
mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST,
|
||||
null, null);
|
||||
getString(R.string.unlock_set_unlock_launch_picker_title));
|
||||
}
|
||||
} else {
|
||||
mFirstPin = savedInstanceState.getString(KEY_FIRST_PIN);
|
||||
|
@@ -379,7 +379,8 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
updateStage(Stage.NeedToConfirm);
|
||||
boolean launchedConfirmationActivity =
|
||||
mChooseLockSettingsHelper.launchConfirmationActivity(
|
||||
CONFIRM_EXISTING_REQUEST, null, null);
|
||||
CONFIRM_EXISTING_REQUEST,
|
||||
getString(R.string.unlock_set_unlock_launch_picker_title));
|
||||
if (!launchedConfirmationActivity) {
|
||||
updateStage(Stage.Introduction);
|
||||
}
|
||||
|
@@ -16,13 +16,14 @@
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Intent;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
|
||||
public final class ChooseLockSettingsHelper {
|
||||
|
||||
static final String EXTRA_KEY_TYPE = "type";
|
||||
@@ -48,64 +49,77 @@ public final class ChooseLockSettingsHelper {
|
||||
|
||||
/**
|
||||
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
|
||||
* @param message optional message to display about the action about to be done
|
||||
* @param details optional detail message to display
|
||||
*
|
||||
* @param title title of the confirmation screen; shown in the action bar
|
||||
* @return true if one exists and we launched an activity to confirm it
|
||||
* @see #onActivityResult(int, int, android.content.Intent)
|
||||
* @see Activity#onActivityResult(int, int, android.content.Intent)
|
||||
*/
|
||||
boolean launchConfirmationActivity(int request, CharSequence message, CharSequence details) {
|
||||
return launchConfirmationActivity(request, message, details, false);
|
||||
boolean launchConfirmationActivity(int request, CharSequence title) {
|
||||
return launchConfirmationActivity(request, title, null, null, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
|
||||
* @param message optional message to display about the action about to be done
|
||||
* @param details optional detail message to display
|
||||
*
|
||||
* @param title title of the confirmation screen; shown in the action bar
|
||||
* @param returnCredentials if true, put credentials into intent. Note that if this is true,
|
||||
this can only be called internally.
|
||||
* this can only be called internally.
|
||||
* @return true if one exists and we launched an activity to confirm it
|
||||
* @see #onActivityResult(int, int, android.content.Intent)
|
||||
* @see Activity#onActivityResult(int, int, android.content.Intent)
|
||||
*/
|
||||
boolean launchConfirmationActivity(int request, CharSequence message, CharSequence details,
|
||||
boolean returnCredentials) {
|
||||
boolean launchConfirmationActivity(int request, CharSequence title, boolean returnCredentials) {
|
||||
return launchConfirmationActivity(request, title, null, null, returnCredentials, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
|
||||
*
|
||||
* @param title title of the confirmation screen; shown in the action bar
|
||||
* @param header header of the confirmation screen; shown as large text
|
||||
* @param description description of the confirmation screen
|
||||
* @param returnCredentials if true, put credentials into intent. Note that if this is true,
|
||||
* this can only be called internally.
|
||||
* @param external specifies whether this activity is launched externally, meaning that it will
|
||||
* get a dark theme and allow fingerprint authentication
|
||||
* @return true if one exists and we launched an activity to confirm it
|
||||
* @see Activity#onActivityResult(int, int, android.content.Intent)
|
||||
*/
|
||||
boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
|
||||
@Nullable CharSequence header, @Nullable CharSequence description,
|
||||
boolean returnCredentials, boolean external) {
|
||||
boolean launched = false;
|
||||
switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
|
||||
launched = confirmPattern(request, message, details, returnCredentials);
|
||||
launched = launchConfirmationActivity(request, title, header, description,
|
||||
returnCredentials
|
||||
? ConfirmLockPattern.InternalActivity.class
|
||||
: ConfirmLockPattern.class, external);
|
||||
break;
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
|
||||
// TODO: update UI layout for ConfirmPassword to show message and details
|
||||
launched = confirmPassword(request, message, returnCredentials);
|
||||
launched = launchConfirmationActivity(request, title, header, description,
|
||||
returnCredentials
|
||||
? ConfirmLockPassword.InternalActivity.class
|
||||
: ConfirmLockPassword.class, external);
|
||||
break;
|
||||
}
|
||||
return launched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch screen to confirm the existing lock pattern.
|
||||
* @param message shown in header of ConfirmLockPattern if not null
|
||||
* @param details shown in footer of ConfirmLockPattern if not null
|
||||
* @param returnCredentials if true, put credentials into intent.
|
||||
* @see #onActivityResult(int, int, android.content.Intent)
|
||||
* @return true if we launched an activity to confirm pattern
|
||||
*/
|
||||
private boolean confirmPattern(int request, CharSequence message,
|
||||
CharSequence details, boolean returnCredentials) {
|
||||
if (!mLockPatternUtils.isLockPatternEnabled()) {
|
||||
return false;
|
||||
}
|
||||
private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header,
|
||||
CharSequence message, Class<?> activityClass, boolean external) {
|
||||
final Intent intent = new Intent();
|
||||
// supply header and footer text in the intent
|
||||
intent.putExtra(ConfirmLockPattern.HEADER_TEXT, message);
|
||||
intent.putExtra(ConfirmLockPattern.FOOTER_TEXT, details);
|
||||
intent.setClassName("com.android.settings",
|
||||
returnCredentials
|
||||
? ConfirmLockPattern.InternalActivity.class.getName()
|
||||
: ConfirmLockPattern.class.getName());
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.HEADER_TEXT, header);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.DETAILS_TEXT, message);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.ALLOW_FP_AUTHENTICATION, external);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.DARK_THEME, external);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_CANCEL_BUTTON, external);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_WHEN_LOCKED, external);
|
||||
intent.setClassName(ConfirmDeviceCredentialBaseFragment.PACKAGE, activityClass.getName());
|
||||
if (mFragment != null) {
|
||||
mFragment.startActivityForResult(intent, request);
|
||||
} else {
|
||||
@@ -113,31 +127,4 @@ public final class ChooseLockSettingsHelper {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch screen to confirm the existing lock password.
|
||||
* @param message shown in header of ConfirmLockPassword if not null
|
||||
* @param returnCredentials if true, put credentials into intent.
|
||||
* @see #onActivityResult(int, int, android.content.Intent)
|
||||
* @return true if we launched an activity to confirm password
|
||||
*/
|
||||
private boolean confirmPassword(int request, CharSequence message,
|
||||
boolean returnCredentials) {
|
||||
if (!mLockPatternUtils.isLockPasswordEnabled()) return false;
|
||||
final Intent intent = new Intent();
|
||||
// supply header text in the intent
|
||||
intent.putExtra(ConfirmLockPattern.HEADER_TEXT, message);
|
||||
intent.setClassName("com.android.settings",
|
||||
returnCredentials
|
||||
? ConfirmLockPassword.InternalActivity.class.getName()
|
||||
: ConfirmLockPassword.class.getName());
|
||||
if (mFragment != null) {
|
||||
mFragment.startActivityForResult(intent, request);
|
||||
} else {
|
||||
mActivity.startActivityForResult(intent, request);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -48,7 +48,8 @@ public class ConfirmDeviceCredentialActivity extends Activity {
|
||||
String details = intent.getStringExtra(KeyguardManager.EXTRA_DESCRIPTION);
|
||||
|
||||
ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(this);
|
||||
if (!helper.launchConfirmationActivity(0 /* request code */, title, details)) {
|
||||
if (!helper.launchConfirmationActivity(0 /* request code */, null /* title */, title,
|
||||
details, false /* returnCredentials */, true /* isExternal */)) {
|
||||
Log.d(TAG, "No pattern, password or PIN set.");
|
||||
setResult(Activity.RESULT_OK);
|
||||
finish();
|
||||
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.KeyguardManager;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class ConfirmDeviceCredentialBaseActivity extends SettingsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedState) {
|
||||
if (getIntent().getBooleanExtra(ConfirmDeviceCredentialBaseFragment.DARK_THEME, false)) {
|
||||
setTheme(R.style.Theme_ConfirmDeviceCredentialsDark);
|
||||
}
|
||||
super.onCreate(savedState);
|
||||
boolean deviceLocked = getSystemService(KeyguardManager.class).isKeyguardLocked();
|
||||
if (deviceLocked && getIntent().getBooleanExtra(
|
||||
ConfirmDeviceCredentialBaseFragment.SHOW_WHEN_LOCKED, false)) {
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
|
||||
}
|
||||
CharSequence msg = getIntent().getStringExtra(
|
||||
ConfirmDeviceCredentialBaseFragment.TITLE_TEXT);
|
||||
setTitle(msg);
|
||||
if (getActionBar() != null) {
|
||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getActionBar().setHomeButtonEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.annotation.Nullable;
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Base fragment to be shared for PIN/Pattern/Password confirmation fragments.
|
||||
*/
|
||||
public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFragment
|
||||
implements FingerprintUiHelper.Callback {
|
||||
|
||||
public static final String PACKAGE = "com.android.settings";
|
||||
public static final String TITLE_TEXT = PACKAGE + ".ConfirmCredentials.title";
|
||||
public static final String HEADER_TEXT = PACKAGE + ".ConfirmCredentials.header";
|
||||
public static final String DETAILS_TEXT = PACKAGE + ".ConfirmCredentials.details";
|
||||
public static final String ALLOW_FP_AUTHENTICATION =
|
||||
PACKAGE + ".ConfirmCredentials.allowFpAuthentication";
|
||||
public static final String DARK_THEME = PACKAGE + ".ConfirmCredentials.darkTheme";
|
||||
public static final String SHOW_CANCEL_BUTTON =
|
||||
PACKAGE + ".ConfirmCredentials.showCancelButton";
|
||||
public static final String SHOW_WHEN_LOCKED =
|
||||
PACKAGE + ".ConfirmCredentials.showWhenLocked";
|
||||
|
||||
private FingerprintUiHelper mFingerprintHelper;
|
||||
private boolean mAllowFpAuthentication;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mAllowFpAuthentication = getActivity().getIntent().getBooleanExtra(
|
||||
ALLOW_FP_AUTHENTICATION, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mFingerprintHelper = new FingerprintUiHelper(
|
||||
(ImageView) view.findViewById(R.id.fingerprintIcon),
|
||||
(TextView) view.findViewById(R.id.errorText), this);
|
||||
boolean showCancelButton = getActivity().getIntent().getBooleanExtra(
|
||||
SHOW_CANCEL_BUTTON, false);
|
||||
Button cancelButton = (Button) view.findViewById(R.id.cancelButton);
|
||||
cancelButton.setVisibility(showCancelButton ? View.VISIBLE : View.GONE);
|
||||
cancelButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getActivity().finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (mAllowFpAuthentication) {
|
||||
mFingerprintHelper.startListening();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (mAllowFpAuthentication) {
|
||||
mFingerprintHelper.stopListening();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticated() {
|
||||
// Check whether we are still active.
|
||||
if (getActivity() != null && getActivity().isResumed()) {
|
||||
authenticationSucceeded(null /* password */);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void authenticationSucceeded(@Nullable String password);
|
||||
|
||||
@Override
|
||||
public void onFingerprintIconVisibilityChanged(boolean visible) {
|
||||
}
|
||||
}
|
@@ -16,14 +16,11 @@
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.PasswordEntryKeyboardHelper;
|
||||
import com.android.internal.widget.PasswordEntryKeyboardView;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
@@ -31,23 +28,18 @@ import android.os.CountDownTimer;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
public class ConfirmLockPassword extends SettingsActivity {
|
||||
|
||||
public static final String PACKAGE = "com.android.settings";
|
||||
public static final String HEADER_TEXT = PACKAGE + ".ConfirmLockPattern.header";
|
||||
public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||
|
||||
public static class InternalActivity extends ConfirmLockPassword {
|
||||
}
|
||||
@@ -65,28 +57,17 @@ public class ConfirmLockPassword extends SettingsActivity {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
// Disable IME on our window since we provide our own keyboard
|
||||
//getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
|
||||
//WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
|
||||
super.onCreate(savedInstanceState);
|
||||
CharSequence msg = getText(R.string.lockpassword_confirm_your_password_header);
|
||||
setTitle(msg);
|
||||
}
|
||||
|
||||
public static class ConfirmLockPasswordFragment extends InstrumentedFragment
|
||||
implements OnClickListener, OnEditorActionListener, TextWatcher {
|
||||
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";
|
||||
private static final long ERROR_MESSAGE_TIMEOUT = 3000;
|
||||
private TextView mPasswordEntry;
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
private TextView mHeaderText;
|
||||
private TextView mHeaderTextView;
|
||||
private TextView mDetailsTextView;
|
||||
private TextView mErrorTextView;
|
||||
private Handler mHandler = new Handler();
|
||||
private PasswordEntryKeyboardHelper mKeyboardHelper;
|
||||
private PasswordEntryKeyboardView mKeyboardView;
|
||||
private Button mContinueButton;
|
||||
private int mNumWrongConfirmAttempts;
|
||||
private CountDownTimer mCountdownTimer;
|
||||
private boolean mIsAlpha;
|
||||
@@ -111,51 +92,35 @@ public class ConfirmLockPassword extends SettingsActivity {
|
||||
Bundle savedInstanceState) {
|
||||
final int storedQuality = mLockPatternUtils.getKeyguardStoredPasswordQuality();
|
||||
View view = inflater.inflate(R.layout.confirm_lock_password, null);
|
||||
// Disable IME on our window since we provide our own keyboard
|
||||
|
||||
view.findViewById(R.id.cancel_button).setOnClickListener(this);
|
||||
mContinueButton = (Button) view.findViewById(R.id.next_button);
|
||||
mContinueButton.setOnClickListener(this);
|
||||
mContinueButton.setEnabled(false); // disable until the user enters at least one char
|
||||
|
||||
mPasswordEntry = (TextView) view.findViewById(R.id.password_entry);
|
||||
mPasswordEntry.setOnEditorActionListener(this);
|
||||
mPasswordEntry.addTextChangedListener(this);
|
||||
|
||||
mKeyboardView = (PasswordEntryKeyboardView) view.findViewById(R.id.keyboard);
|
||||
mHeaderText = (TextView) view.findViewById(R.id.headerText);
|
||||
mHeaderTextView = (TextView) view.findViewById(R.id.headerText);
|
||||
mDetailsTextView = (TextView) view.findViewById(R.id.detailsText);
|
||||
mErrorTextView = (TextView) view.findViewById(R.id.errorText);
|
||||
mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == storedQuality
|
||||
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == storedQuality
|
||||
|| DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == storedQuality;
|
||||
|
||||
Intent intent = getActivity().getIntent();
|
||||
if (intent != null) {
|
||||
CharSequence headerMessage = intent.getCharSequenceExtra(HEADER_TEXT);
|
||||
CharSequence headerMessage = intent.getCharSequenceExtra(
|
||||
ConfirmDeviceCredentialBaseFragment.HEADER_TEXT);
|
||||
CharSequence detailsMessage = intent.getCharSequenceExtra(
|
||||
ConfirmDeviceCredentialBaseFragment.DETAILS_TEXT);
|
||||
if (TextUtils.isEmpty(headerMessage)) {
|
||||
headerMessage = getString(getDefaultHeader());
|
||||
}
|
||||
mHeaderText.setText(headerMessage);
|
||||
if (TextUtils.isEmpty(detailsMessage)) {
|
||||
detailsMessage = getString(getDefaultDetails());
|
||||
}
|
||||
mHeaderTextView.setText(headerMessage);
|
||||
mDetailsTextView.setText(detailsMessage);
|
||||
}
|
||||
|
||||
final Activity activity = getActivity();
|
||||
mKeyboardHelper = new PasswordEntryKeyboardHelper(activity,
|
||||
mKeyboardView, mPasswordEntry);
|
||||
mKeyboardHelper.setKeyboardMode(mIsAlpha ?
|
||||
PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
|
||||
: PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
|
||||
mKeyboardView.requestFocus();
|
||||
|
||||
int currentType = mPasswordEntry.getInputType();
|
||||
mPasswordEntry.setInputType(mIsAlpha ? currentType
|
||||
: (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD));
|
||||
|
||||
if (activity instanceof SettingsActivity) {
|
||||
final SettingsActivity sa = (SettingsActivity) activity;
|
||||
int id = getDefaultHeader();
|
||||
CharSequence title = getText(id);
|
||||
sa.setTitle(title);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -164,10 +129,19 @@ public class ConfirmLockPassword extends SettingsActivity {
|
||||
: R.string.lockpassword_confirm_your_pin_header;
|
||||
}
|
||||
|
||||
private int getDefaultDetails() {
|
||||
return mIsAlpha ? R.string.lockpassword_confirm_your_password_generic
|
||||
: R.string.lockpassword_confirm_your_pin_generic;
|
||||
}
|
||||
|
||||
private int getErrorMessage() {
|
||||
return mIsAlpha ? R.string.lockpassword_invalid_password
|
||||
: R.string.lockpassword_invalid_pin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mKeyboardView.requestFocus();
|
||||
if (mCountdownTimer != null) {
|
||||
mCountdownTimer.cancel();
|
||||
mCountdownTimer = null;
|
||||
@@ -181,9 +155,7 @@ public class ConfirmLockPassword extends SettingsActivity {
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
// TODO Auto-generated method stub
|
||||
super.onResume();
|
||||
mKeyboardView.requestFocus();
|
||||
long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
|
||||
if (deadline != 0) {
|
||||
handleAttemptLockout(deadline);
|
||||
@@ -196,33 +168,35 @@ public class ConfirmLockPassword extends SettingsActivity {
|
||||
outState.putInt(KEY_NUM_WRONG_CONFIRM_ATTEMPTS, mNumWrongConfirmAttempts);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void authenticationSucceeded(@Nullable String password) {
|
||||
Intent intent = new Intent();
|
||||
if (getActivity() instanceof ConfirmLockPassword.InternalActivity) {
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
|
||||
mIsAlpha ? StorageManager.CRYPT_TYPE_PASSWORD
|
||||
: StorageManager.CRYPT_TYPE_PIN);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password);
|
||||
}
|
||||
getActivity().setResult(RESULT_OK, intent);
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
private void handleNext() {
|
||||
final String pin = mPasswordEntry.getText().toString();
|
||||
if (mLockPatternUtils.checkPassword(pin)) {
|
||||
|
||||
Intent intent = new Intent();
|
||||
if (getActivity() instanceof ConfirmLockPassword.InternalActivity) {
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
|
||||
mIsAlpha ? StorageManager.CRYPT_TYPE_PASSWORD
|
||||
: StorageManager.CRYPT_TYPE_PIN);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pin);
|
||||
}
|
||||
|
||||
getActivity().setResult(RESULT_OK, intent);
|
||||
getActivity().finish();
|
||||
authenticationSucceeded(pin);
|
||||
} else {
|
||||
if (++mNumWrongConfirmAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
|
||||
long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
|
||||
handleAttemptLockout(deadline);
|
||||
} else {
|
||||
showError(R.string.lockpattern_need_to_unlock_wrong);
|
||||
showError(getErrorMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
|
||||
long elapsedRealtime = SystemClock.elapsedRealtime();
|
||||
showError(R.string.lockpattern_too_many_failed_confirmation_attempts_header, 0);
|
||||
mPasswordEntry.setEnabled(false);
|
||||
mCountdownTimer = new CountDownTimer(
|
||||
elapsedRealtimeDeadline - elapsedRealtime,
|
||||
@@ -231,15 +205,15 @@ public class ConfirmLockPassword extends SettingsActivity {
|
||||
@Override
|
||||
public void onTick(long millisUntilFinished) {
|
||||
final int secondsCountdown = (int) (millisUntilFinished / 1000);
|
||||
mHeaderText.setText(getString(
|
||||
R.string.lockpattern_too_many_failed_confirmation_attempts_footer,
|
||||
secondsCountdown));
|
||||
showError(getString(
|
||||
R.string.lockpattern_too_many_failed_confirmation_attempts,
|
||||
secondsCountdown), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
mPasswordEntry.setEnabled(true);
|
||||
mHeaderText.setText(getDefaultHeader());
|
||||
mErrorTextView.setText("");
|
||||
mNumWrongConfirmAttempts = 0;
|
||||
}
|
||||
}.start();
|
||||
@@ -264,13 +238,13 @@ public class ConfirmLockPassword extends SettingsActivity {
|
||||
|
||||
private final Runnable mResetErrorRunnable = new Runnable() {
|
||||
public void run() {
|
||||
mHeaderText.setText(getDefaultHeader());
|
||||
mErrorTextView.setText("");
|
||||
}
|
||||
};
|
||||
|
||||
private void showError(int msg, long timeout) {
|
||||
mHeaderText.setText(msg);
|
||||
mHeaderText.announceForAccessibility(mHeaderText.getText());
|
||||
private void showError(CharSequence msg, long timeout) {
|
||||
mErrorTextView.setText(msg);
|
||||
mErrorTextView.announceForAccessibility(mErrorTextView.getText());
|
||||
mPasswordEntry.setText(null);
|
||||
mHandler.removeCallbacks(mResetErrorRunnable);
|
||||
if (timeout != 0) {
|
||||
@@ -278,6 +252,10 @@ public class ConfirmLockPassword extends SettingsActivity {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -289,16 +267,5 @@ public class ConfirmLockPassword extends SettingsActivity {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// {@link TextWatcher} methods.
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
public void afterTextChanged(Editable s) {
|
||||
mContinueButton.setEnabled(mPasswordEntry.getText().length() > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -22,13 +22,14 @@ import com.android.internal.widget.LockPatternView;
|
||||
import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
|
||||
import com.android.internal.widget.LockPatternView.Cell;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.Intent;
|
||||
import android.os.CountDownTimer;
|
||||
import android.os.SystemClock;
|
||||
import android.os.Bundle;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.TextView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -42,36 +43,17 @@ import java.util.List;
|
||||
* Sets an activity result of {@link Activity#RESULT_OK} when the user
|
||||
* successfully confirmed their pattern.
|
||||
*/
|
||||
public class ConfirmLockPattern extends SettingsActivity {
|
||||
public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
||||
|
||||
public static class InternalActivity extends ConfirmLockPattern {
|
||||
}
|
||||
|
||||
/**
|
||||
* Names of {@link CharSequence} fields within the originating {@link Intent}
|
||||
* that are used to configure the keyguard confirmation view's labeling.
|
||||
* The view will use the system-defined resource strings for any labels that
|
||||
* the caller does not supply.
|
||||
*/
|
||||
public static final String PACKAGE = "com.android.settings";
|
||||
public static final String HEADER_TEXT = PACKAGE + ".ConfirmLockPattern.header";
|
||||
public static final String FOOTER_TEXT = PACKAGE + ".ConfirmLockPattern.footer";
|
||||
public static final String HEADER_WRONG_TEXT = PACKAGE + ".ConfirmLockPattern.header_wrong";
|
||||
public static final String FOOTER_WRONG_TEXT = PACKAGE + ".ConfirmLockPattern.footer_wrong";
|
||||
|
||||
private enum Stage {
|
||||
NeedToUnlock,
|
||||
NeedToUnlockWrong,
|
||||
LockedOut
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
CharSequence msg = getText(R.string.lockpassword_confirm_your_pattern_header);
|
||||
setTitle(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent getIntent() {
|
||||
Intent modIntent = new Intent(super.getIntent());
|
||||
@@ -85,7 +67,7 @@ public class ConfirmLockPattern extends SettingsActivity {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class ConfirmLockPatternFragment extends InstrumentedFragment {
|
||||
public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment {
|
||||
|
||||
// how long we wait to clear a wrong pattern
|
||||
private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
|
||||
@@ -98,13 +80,14 @@ public class ConfirmLockPattern extends SettingsActivity {
|
||||
private CountDownTimer mCountdownTimer;
|
||||
|
||||
private TextView mHeaderTextView;
|
||||
private TextView mFooterTextView;
|
||||
private TextView mDetailsTextView;
|
||||
private TextView mErrorTextView;
|
||||
private View mLeftSpacerLandscape;
|
||||
private View mRightSpacerLandscape;
|
||||
|
||||
// caller-supplied text for various prompts
|
||||
private CharSequence mHeaderText;
|
||||
private CharSequence mFooterText;
|
||||
private CharSequence mHeaderWrongText;
|
||||
private CharSequence mFooterWrongText;
|
||||
private CharSequence mDetailsText;
|
||||
|
||||
// required constructor for fragments
|
||||
public ConfirmLockPatternFragment() {
|
||||
@@ -123,7 +106,10 @@ public class ConfirmLockPattern extends SettingsActivity {
|
||||
View view = inflater.inflate(R.layout.confirm_lock_pattern, null);
|
||||
mHeaderTextView = (TextView) view.findViewById(R.id.headerText);
|
||||
mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern);
|
||||
mFooterTextView = (TextView) view.findViewById(R.id.footerText);
|
||||
mDetailsTextView = (TextView) view.findViewById(R.id.detailsText);
|
||||
mErrorTextView = (TextView) view.findViewById(R.id.errorText);
|
||||
mLeftSpacerLandscape = view.findViewById(R.id.leftSpacer);
|
||||
mRightSpacerLandscape = view.findViewById(R.id.rightSpacer);
|
||||
|
||||
// make it so unhandled touch events within the unlock screen go to the
|
||||
// lock pattern view.
|
||||
@@ -133,10 +119,10 @@ public class ConfirmLockPattern extends SettingsActivity {
|
||||
|
||||
Intent intent = getActivity().getIntent();
|
||||
if (intent != null) {
|
||||
mHeaderText = intent.getCharSequenceExtra(HEADER_TEXT);
|
||||
mFooterText = intent.getCharSequenceExtra(FOOTER_TEXT);
|
||||
mHeaderWrongText = intent.getCharSequenceExtra(HEADER_WRONG_TEXT);
|
||||
mFooterWrongText = intent.getCharSequenceExtra(FOOTER_WRONG_TEXT);
|
||||
mHeaderText = intent.getCharSequenceExtra(
|
||||
ConfirmDeviceCredentialBaseFragment.HEADER_TEXT);
|
||||
mDetailsText = intent.getCharSequenceExtra(
|
||||
ConfirmDeviceCredentialBaseFragment.DETAILS_TEXT);
|
||||
}
|
||||
|
||||
mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
|
||||
@@ -199,28 +185,21 @@ public class ConfirmLockPattern extends SettingsActivity {
|
||||
if (mHeaderText != null) {
|
||||
mHeaderTextView.setText(mHeaderText);
|
||||
} else {
|
||||
mHeaderTextView.setText(R.string.lockpattern_need_to_unlock);
|
||||
mHeaderTextView.setText(R.string.lockpassword_confirm_your_pattern_header);
|
||||
}
|
||||
if (mFooterText != null) {
|
||||
mFooterTextView.setText(mFooterText);
|
||||
if (mDetailsText != null) {
|
||||
mDetailsTextView.setText(mDetailsText);
|
||||
} else {
|
||||
mFooterTextView.setText(R.string.lockpattern_need_to_unlock_footer);
|
||||
mDetailsTextView.setText(
|
||||
R.string.lockpassword_confirm_your_pattern_generic);
|
||||
}
|
||||
mErrorTextView.setText("");
|
||||
|
||||
mLockPatternView.setEnabled(true);
|
||||
mLockPatternView.enableInput();
|
||||
break;
|
||||
case NeedToUnlockWrong:
|
||||
if (mHeaderWrongText != null) {
|
||||
mHeaderTextView.setText(mHeaderWrongText);
|
||||
} else {
|
||||
mHeaderTextView.setText(R.string.lockpattern_need_to_unlock_wrong);
|
||||
}
|
||||
if (mFooterWrongText != null) {
|
||||
mFooterTextView.setText(mFooterWrongText);
|
||||
} else {
|
||||
mFooterTextView.setText(R.string.lockpattern_need_to_unlock_wrong_footer);
|
||||
}
|
||||
mErrorTextView.setText(R.string.lockpattern_need_to_unlock_wrong);
|
||||
|
||||
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
|
||||
mLockPatternView.setEnabled(true);
|
||||
@@ -252,6 +231,28 @@ public class ConfirmLockPattern extends SettingsActivity {
|
||||
mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void authenticationSucceeded(@Nullable String password) {
|
||||
Intent intent = new Intent();
|
||||
if (getActivity() instanceof ConfirmLockPattern.InternalActivity) {
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
|
||||
StorageManager.CRYPT_TYPE_PATTERN);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password);
|
||||
}
|
||||
getActivity().setResult(Activity.RESULT_OK, intent);
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFingerprintIconVisibilityChanged(boolean visible) {
|
||||
if (mLeftSpacerLandscape != null && mRightSpacerLandscape != null) {
|
||||
|
||||
// In landscape, adjust spacing depending on fingerprint icon visibility.
|
||||
mLeftSpacerLandscape.setVisibility(visible ? View.GONE : View.VISIBLE);
|
||||
mRightSpacerLandscape.setVisibility(visible ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The pattern listener that responds according to a user confirming
|
||||
* an existing lock pattern.
|
||||
@@ -273,17 +274,7 @@ public class ConfirmLockPattern extends SettingsActivity {
|
||||
|
||||
public void onPatternDetected(List<LockPatternView.Cell> pattern) {
|
||||
if (mLockPatternUtils.checkPattern(pattern)) {
|
||||
|
||||
Intent intent = new Intent();
|
||||
if (getActivity() instanceof ConfirmLockPattern.InternalActivity) {
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
|
||||
StorageManager.CRYPT_TYPE_PATTERN);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
|
||||
LockPatternUtils.patternToString(pattern));
|
||||
}
|
||||
|
||||
getActivity().setResult(Activity.RESULT_OK, intent);
|
||||
getActivity().finish();
|
||||
authenticationSucceeded(LockPatternUtils.patternToString(pattern));
|
||||
} else {
|
||||
if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL &&
|
||||
++mNumWrongConfirmAttempts
|
||||
@@ -308,10 +299,9 @@ public class ConfirmLockPattern extends SettingsActivity {
|
||||
|
||||
@Override
|
||||
public void onTick(long millisUntilFinished) {
|
||||
mHeaderTextView.setText(R.string.lockpattern_too_many_failed_confirmation_attempts_header);
|
||||
final int secondsCountdown = (int) (millisUntilFinished / 1000);
|
||||
mFooterTextView.setText(getString(
|
||||
R.string.lockpattern_too_many_failed_confirmation_attempts_footer,
|
||||
mErrorTextView.setText(getString(
|
||||
R.string.lockpattern_too_many_failed_confirmation_attempts,
|
||||
secondsCountdown));
|
||||
}
|
||||
|
||||
|
@@ -439,9 +439,8 @@ public final class CredentialStorage extends Activity {
|
||||
private boolean confirmKeyGuard() {
|
||||
Resources res = getResources();
|
||||
boolean launched = new ChooseLockSettingsHelper(this)
|
||||
.launchConfirmationActivity(CONFIRM_KEY_GUARD_REQUEST, null,
|
||||
res.getText(R.string.credentials_install_gesture_explanation),
|
||||
true);
|
||||
.launchConfirmationActivity(CONFIRM_KEY_GUARD_REQUEST,
|
||||
res.getText(R.string.credentials_title), true);
|
||||
return launched;
|
||||
}
|
||||
|
||||
|
@@ -166,9 +166,8 @@ public class CryptKeeperSettings extends InstrumentedFragment {
|
||||
return true;
|
||||
}
|
||||
|
||||
return helper.launchConfirmationActivity(request, null,
|
||||
res.getText(R.string.crypt_keeper_confirm_encrypt),
|
||||
true);
|
||||
return helper.launchConfirmationActivity(request,
|
||||
res.getText(R.string.crypt_keeper_encrypt_title), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1610,10 +1610,8 @@ public class DevelopmentSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
|
||||
private boolean showKeyguardConfirmation(Resources resources, int requestCode) {
|
||||
return new ChooseLockSettingsHelper(getActivity(), this)
|
||||
.launchConfirmationActivity(requestCode,
|
||||
resources.getString(R.string.oem_unlock_enable_pin_prompt),
|
||||
resources.getString(R.string.oem_unlock_enable_pin_description));
|
||||
return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity(
|
||||
requestCode, resources.getString(R.string.oem_unlock_enable));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
119
src/com/android/settings/FingerprintUiHelper.java
Normal file
119
src/com/android/settings/FingerprintUiHelper.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Vibrator;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Small helper class to manage text/icon around fingerprint authentication UI.
|
||||
*/
|
||||
public class FingerprintUiHelper extends FingerprintManager.AuthenticationCallback {
|
||||
|
||||
private static final long ERROR_TIMEOUT = 1300;
|
||||
private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
|
||||
private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};
|
||||
|
||||
private ImageView mIcon;
|
||||
private TextView mErrorTextView;
|
||||
private CancellationSignal mCancellationSignal;
|
||||
|
||||
private Callback mCallback;
|
||||
private FingerprintManager mFingerprintManager;
|
||||
|
||||
public FingerprintUiHelper(ImageView icon, TextView errorTextView, Callback callback) {
|
||||
mFingerprintManager = icon.getContext().getSystemService(FingerprintManager.class);
|
||||
mIcon = icon;
|
||||
mErrorTextView = errorTextView;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
public void startListening() {
|
||||
if (mFingerprintManager.getEnrolledFingerprints().size() > 0) {
|
||||
mCancellationSignal = new CancellationSignal();
|
||||
mFingerprintManager.authenticate(null, mCancellationSignal, this, 0 /* flags */);
|
||||
setFingerprintIconVisibility(true);
|
||||
mIcon.setImageResource(R.drawable.ic_fingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopListening() {
|
||||
mCancellationSignal.cancel();
|
||||
mCancellationSignal = null;
|
||||
}
|
||||
|
||||
private void setFingerprintIconVisibility(boolean visible) {
|
||||
mIcon.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
mCallback.onFingerprintIconVisibilityChanged(visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationError(int errMsgId, CharSequence errString) {
|
||||
showError(errString);
|
||||
setFingerprintIconVisibility(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
|
||||
showError(helpString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailed() {
|
||||
showError(mIcon.getResources().getString(
|
||||
R.string.fingerprint_not_recognized));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
|
||||
vibrateFingerprintSuccess();
|
||||
mCallback.onAuthenticated();
|
||||
}
|
||||
|
||||
private void showError(CharSequence error) {
|
||||
vibrateFingerprintError();
|
||||
mIcon.setImageResource(R.drawable.ic_fingerprint_error);
|
||||
mErrorTextView.setText(error);
|
||||
mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
|
||||
mErrorTextView.postDelayed(mResetErrorTextRunnable, ERROR_TIMEOUT);
|
||||
}
|
||||
|
||||
private void vibrateFingerprintError() {
|
||||
mIcon.getContext().getSystemService(Vibrator.class).vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
|
||||
}
|
||||
|
||||
private void vibrateFingerprintSuccess() {
|
||||
mIcon.getContext().getSystemService(Vibrator.class).vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
|
||||
}
|
||||
|
||||
private Runnable mResetErrorTextRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mErrorTextView.setText("");
|
||||
mIcon.setImageResource(R.drawable.ic_fingerprint);
|
||||
}
|
||||
};
|
||||
|
||||
public interface Callback {
|
||||
void onAuthenticated();
|
||||
void onFingerprintIconVisibilityChanged(boolean visible);
|
||||
}
|
||||
}
|
@@ -75,8 +75,8 @@ public class MasterClear extends InstrumentedFragment {
|
||||
*/
|
||||
private boolean runKeyguardConfirmation(int request) {
|
||||
Resources res = getActivity().getResources();
|
||||
return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity(request,
|
||||
null, res.getText(R.string.master_clear_gesture_explanation));
|
||||
return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity(
|
||||
request, res.getText(R.string.master_clear_title));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -72,9 +72,8 @@ public class MediaFormat extends Activity {
|
||||
* component as a subactivity
|
||||
*/
|
||||
private boolean runKeyguardConfirmation(int request) {
|
||||
return new ChooseLockSettingsHelper(this)
|
||||
.launchConfirmationActivity(request, null,
|
||||
getText(R.string.media_format_gesture_explanation));
|
||||
return new ChooseLockSettingsHelper(this).launchConfirmationActivity(request,
|
||||
getText(R.string.media_format_title));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -78,8 +78,8 @@ public class ResetNetwork extends InstrumentedFragment {
|
||||
*/
|
||||
private boolean runKeyguardConfirmation(int request) {
|
||||
Resources res = getActivity().getResources();
|
||||
return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity(request,
|
||||
null, res.getText(R.string.reset_network_gesture_explanation));
|
||||
return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity(
|
||||
request, res.getText(R.string.reset_network_title));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -603,8 +603,9 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
ChooseLockSettingsHelper helper =
|
||||
new ChooseLockSettingsHelper(this.getActivity(), this);
|
||||
mTrustAgentClickIntent = preference.getIntent();
|
||||
if (!helper.launchConfirmationActivity(CHANGE_TRUST_AGENT_SETTINGS, null, null) &&
|
||||
mTrustAgentClickIntent != null) {
|
||||
boolean confirmationLaunched = helper.launchConfirmationActivity(
|
||||
CHANGE_TRUST_AGENT_SETTINGS, preference.getTitle());
|
||||
if (!confirmationLaunched&& mTrustAgentClickIntent != null) {
|
||||
// If this returns false, it means no password confirmation is required.
|
||||
startActivity(mTrustAgentClickIntent);
|
||||
mTrustAgentClickIntent = null;
|
||||
|
Reference in New Issue
Block a user