FileDocCategorySizeDatePackage
KeyguardAccountView.javaAPI DocAndroid 5.1 API11595Thu Mar 12 22:22:42 GMT 2015com.android.keyguard

KeyguardAccountView

public class KeyguardAccountView extends android.widget.LinearLayout implements android.text.TextWatcher, View.OnClickListener, KeyguardSecurityView
When the user forgets their password a bunch of times, we fall back on their account's login/password to unlock the phone (and reset their lock pattern).

Fields Summary
private static final String
LOCK_PATTERN_PACKAGE
private static final String
LOCK_PATTERN_CLASS
private KeyguardSecurityCallback
mCallback
private com.android.internal.widget.LockPatternUtils
mLockPatternUtils
private android.widget.EditText
mLogin
private android.widget.EditText
mPassword
private android.widget.Button
mOk
public boolean
mEnableFallback
private SecurityMessageDisplay
mSecurityMessageDisplay
private android.app.ProgressDialog
mCheckingDialog
Shown while making asynchronous check of password.
Constructors Summary
public KeyguardAccountView(android.content.Context context)


       
        this(context, null, 0);
    
public KeyguardAccountView(android.content.Context context, android.util.AttributeSet attrs)

        this(context, attrs, 0);
    
public KeyguardAccountView(android.content.Context context, android.util.AttributeSet attrs, int defStyle)

        super(context, attrs, defStyle);
        mLockPatternUtils = new LockPatternUtils(getContext());
    
Methods Summary
public voidafterTextChanged(android.text.Editable s)

    
private voidasyncCheckPassword()

        mCallback.userActivity();
        final String login = mLogin.getText().toString();
        final String password = mPassword.getText().toString();
        Account account = findIntendedAccount(login);
        if (account == null) {
            postOnCheckPasswordResult(false);
            return;
        }
        getProgressDialog().show();
        Bundle options = new Bundle();
        options.putString(AccountManager.KEY_PASSWORD, password);
        AccountManager.get(mContext).confirmCredentialsAsUser(account, options, null /* activity */,
                new AccountManagerCallback<Bundle>() {
            public void run(AccountManagerFuture<Bundle> future) {
                try {
                    mCallback.userActivity();
                    final Bundle result = future.getResult();
                    final boolean verified = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
                    postOnCheckPasswordResult(verified);
                } catch (OperationCanceledException e) {
                    postOnCheckPasswordResult(false);
                } catch (IOException e) {
                    postOnCheckPasswordResult(false);
                } catch (AuthenticatorException e) {
                    postOnCheckPasswordResult(false);
                } finally {
                    mLogin.post(new Runnable() {
                        public void run() {
                            getProgressDialog().hide();
                        }
                    });
                }
            }
        }, null /* handler */, new UserHandle(mLockPatternUtils.getCurrentUser()));
    
public voidbeforeTextChanged(java.lang.CharSequence s, int start, int count, int after)

    
public voidcleanUp()
{@inheritDoc}

        if (mCheckingDialog != null) {
            mCheckingDialog.hide();
        }
        mCallback = null;
        mLockPatternUtils = null;
    
public booleandispatchKeyEvent(android.view.KeyEvent event)

        if (event.getAction() == KeyEvent.ACTION_DOWN
                && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            if (mLockPatternUtils.isPermanentlyLocked()) {
                mCallback.dismiss(false);
            } else {
                // TODO: mCallback.forgotPattern(false);
            }
            return true;
        }
        return super.dispatchKeyEvent(event);
    
private android.accounts.AccountfindIntendedAccount(java.lang.String username)
Given the string the user entered in the 'username' field, find the stored account that they probably intended. Prefer, in order: - an exact match for what was typed, or - a case-insensitive match for what was typed, or - if they didn't include a domain, an exact match of the username, or - if they didn't include a domain, a case-insensitive match of the username. If there is a tie for the best match, choose neither -- the user needs to be more specific.

return
an account name from the database, or null if we can't find a single best match.

        Account[] accounts = AccountManager.get(mContext).getAccountsByTypeAsUser("com.google",
                new UserHandle(mLockPatternUtils.getCurrentUser()));

        // Try to figure out which account they meant if they
        // typed only the username (and not the domain), or got
        // the case wrong.

        Account bestAccount = null;
        int bestScore = 0;
        for (Account a: accounts) {
            int score = 0;
            if (username.equals(a.name)) {
                score = 4;
            } else if (username.equalsIgnoreCase(a.name)) {
                score = 3;
            } else if (username.indexOf('@") < 0) {
                int i = a.name.indexOf('@");
                if (i >= 0) {
                    String aUsername = a.name.substring(0, i);
                    if (username.equals(aUsername)) {
                        score = 2;
                    } else if (username.equalsIgnoreCase(aUsername)) {
                        score = 1;
                    }
                }
            }
            if (score > bestScore) {
                bestAccount = a;
                bestScore = score;
            } else if (score == bestScore) {
                bestAccount = null;
            }
        }
        return bestAccount;
    
public KeyguardSecurityCallbackgetCallback()

        return mCallback;
    
private android.app.DialoggetProgressDialog()

        if (mCheckingDialog == null) {
            mCheckingDialog = new ProgressDialog(mContext);
            mCheckingDialog.setMessage(
                    mContext.getString(R.string.kg_login_checking_password));
            mCheckingDialog.setIndeterminate(true);
            mCheckingDialog.setCancelable(false);
            mCheckingDialog.getWindow().setType(
                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        }
        return mCheckingDialog;
    
public voidhideBouncer(int duration)

    
public booleanneedsInput()

        return true;
    
public voidonClick(android.view.View v)

        mCallback.userActivity();
        if (v == mOk) {
            asyncCheckPassword();
        }
    
protected voidonFinishInflate()

        super.onFinishInflate();

        mLogin = (EditText) findViewById(R.id.login);
        mLogin.setFilters(new InputFilter[] { new LoginFilter.UsernameFilterGeneric() } );
        mLogin.addTextChangedListener(this);

        mPassword = (EditText) findViewById(R.id.password);
        mPassword.addTextChangedListener(this);

        mOk = (Button) findViewById(R.id.ok);
        mOk.setOnClickListener(this);

        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
        reset();
    
public voidonPause()


    
protected booleanonRequestFocusInDescendants(int direction, android.graphics.Rect previouslyFocusedRect)

        // send focus to the login field
        return mLogin.requestFocus(direction, previouslyFocusedRect);
    
public voidonResume(int reason)

        reset();
    
public voidonTextChanged(java.lang.CharSequence s, int start, int before, int count)

        if (mCallback != null) {
            mCallback.userActivity();
        }
    
private voidpostOnCheckPasswordResult(boolean success)

        // ensure this runs on UI thread
        mLogin.post(new Runnable() {
            public void run() {
                if (success) {
                    // clear out forgotten password
                    mLockPatternUtils.setPermanentlyLocked(false);
                    mLockPatternUtils.setLockPatternEnabled(false);
                    mLockPatternUtils.saveLockPattern(null);

                    // launch the 'choose lock pattern' activity so
                    // the user can pick a new one if they want to
                    Intent intent = new Intent();
                    intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    mContext.startActivityAsUser(intent,
                            new UserHandle(mLockPatternUtils.getCurrentUser()));
                    mCallback.reportUnlockAttempt(true);

                    // dismiss keyguard
                    mCallback.dismiss(true);
                } else {
                    mSecurityMessageDisplay.setMessage(R.string.kg_login_invalid_input, true);
                    mPassword.setText("");
                    mCallback.reportUnlockAttempt(false);
                }
            }
        });
    
public voidreset()

        // start fresh
        mLogin.setText("");
        mPassword.setText("");
        mLogin.requestFocus();
        boolean permLocked = mLockPatternUtils.isPermanentlyLocked();
        mSecurityMessageDisplay.setMessage(permLocked ? R.string.kg_login_too_many_attempts :
            R.string.kg_login_instructions, permLocked ? true : false);
    
public voidsetKeyguardCallback(KeyguardSecurityCallback callback)

        mCallback = callback;
    
public voidsetLockPatternUtils(com.android.internal.widget.LockPatternUtils utils)

        mLockPatternUtils = utils;
    
public voidshowBouncer(int duration)

    
public voidshowUsabilityHint()

    
public voidstartAppearAnimation()

        // TODO.
    
public booleanstartDisappearAnimation(java.lang.Runnable finishRunnable)

        return false;