11f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/*
2dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Copyright (C) 2012 The Android Open Source Project
31f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
41f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
51f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * you may not use this file except in compliance with the License.
61f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * You may obtain a copy of the License at
71f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
81f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
91f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * See the License for the specific language governing permissions and
141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * limitations under the License.
151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
165ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerpackage com.android.keyguard;
171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
184e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintanaimport android.accounts.Account;
194e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintanaimport android.accounts.AccountManager;
20dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.accounts.AccountManagerCallback;
211c01c8bc79941471857338bae011fd0a6790f89fFred Quintanaimport android.accounts.AccountManagerFuture;
221c01c8bc79941471857338bae011fd0a6790f89fFred Quintanaimport android.accounts.AuthenticatorException;
23dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.accounts.OperationCanceledException;
24dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.app.Dialog;
25dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.app.ProgressDialog;
261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context;
271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Intent;
281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.graphics.Rect;
29dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.os.Bundle;
302c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasaniimport android.os.UserHandle;
311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.text.Editable;
321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.text.InputFilter;
331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.text.LoginFilter;
341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.text.TextWatcher;
35dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.AttributeSet;
361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.KeyEvent;
371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.View;
3884999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaenimport android.view.WindowManager;
391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.Button;
401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.EditText;
41dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.widget.LinearLayout;
42dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
43dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.widget.LockPatternUtils;
441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
451c01c8bc79941471857338bae011fd0a6790f89fFred Quintanaimport java.io.IOException;
461c01c8bc79941471857338bae011fd0a6790f89fFred Quintana
471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/**
481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * When the user forgets their password a bunch of times, we fall back on their
491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * account's login/password to unlock the phone (and reset their lock pattern).
501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
51dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpublic class KeyguardAccountView extends LinearLayout implements KeyguardSecurityView,
526b05d58018c2806459c121e507c005639b74aee9Jim Miller        View.OnClickListener, TextWatcher {
53dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private static final int AWAKE_POKE_MILLIS = 30000;
541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final String LOCK_PATTERN_PACKAGE = "com.android.settings";
55aae641bc6404d8cee8840769881742df8963aa5bBrian Colonna    private static final String LOCK_PATTERN_CLASS = LOCK_PATTERN_PACKAGE + ".ChooseLockGeneric";
561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
57dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardSecurityCallback mCallback;
588b886fab5496b0b1f5193f21855220176deddc37Jim Miller    private LockPatternUtils mLockPatternUtils;
591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private EditText mLogin;
601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private EditText mPassword;
611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Button mOk;
62dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public boolean mEnableFallback;
630ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    private SecurityMessageDisplay mSecurityMessageDisplay;
641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
6684999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen     * Shown while making asynchronous check of password.
6784999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen     */
6884999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen    private ProgressDialog mCheckingDialog;
6984999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen
70dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardAccountView(Context context) {
71dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        this(context, null, 0);
72dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
74dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardAccountView(Context context, AttributeSet attrs) {
75dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        this(context, attrs, 0);
76dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
78dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardAccountView(Context context, AttributeSet attrs, int defStyle) {
79dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super(context, attrs, defStyle);
80dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = new LockPatternUtils(getContext());
81dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
83dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
84dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onFinishInflate() {
85dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onFinishInflate();
861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mLogin = (EditText) findViewById(R.id.login);
881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mLogin.setFilters(new InputFilter[] { new LoginFilter.UsernameFilterGeneric() } );
891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mLogin.addTextChangedListener(this);
901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mPassword = (EditText) findViewById(R.id.password);
921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mPassword.addTextChangedListener(this);
931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mOk = (Button) findViewById(R.id.ok);
951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mOk.setOnClickListener(this);
960b728244dc87b4a453f2191c2cb37a86e91aee0aJim Miller
970b728244dc87b4a453f2191c2cb37a86e91aee0aJim Miller        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
98dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        reset();
99dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
101dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
102dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mCallback = callback;
103dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
104dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
105dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void setLockPatternUtils(LockPatternUtils utils) {
106dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = utils;
107dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1086b05d58018c2806459c121e507c005639b74aee9Jim Miller
109dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardSecurityCallback getCallback() {
110dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return mCallback;
1114e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintana    }
1121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
113dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void afterTextChanged(Editable s) {
1151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
1181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onTextChanged(CharSequence s, int start, int before, int count) {
121dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (mCallback != null) {
122dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mCallback.userActivity(AWAKE_POKE_MILLIS);
123dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
1241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
1271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    protected boolean onRequestFocusInDescendants(int direction,
1281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Rect previouslyFocusedRect) {
1291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // send focus to the login field
1301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return mLogin.requestFocus(direction, previouslyFocusedRect);
1311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public boolean needsInput() {
1341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return true;
1351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
137dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void reset() {
1381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // start fresh
1391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mLogin.setText("");
1401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mPassword.setText("");
1411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mLogin.requestFocus();
1420a4f900463024908220d0c9bf4b291a6e1284846Adam Cohen        boolean permLocked = mLockPatternUtils.isPermanentlyLocked();
1430a4f900463024908220d0c9bf4b291a6e1284846Adam Cohen        mSecurityMessageDisplay.setMessage(permLocked ? R.string.kg_login_too_many_attempts :
1440a4f900463024908220d0c9bf4b291a6e1284846Adam Cohen            R.string.kg_login_instructions, permLocked ? true : false);
1451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
1481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void cleanUp() {
14984999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen        if (mCheckingDialog != null) {
15084999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            mCheckingDialog.hide();
15184999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen        }
1528b886fab5496b0b1f5193f21855220176deddc37Jim Miller        mCallback = null;
1538b886fab5496b0b1f5193f21855220176deddc37Jim Miller        mLockPatternUtils = null;
1541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onClick(View v) {
157dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mCallback.userActivity(0);
1581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (v == mOk) {
1591c01c8bc79941471857338bae011fd0a6790f89fFred Quintana            asyncCheckPassword();
1601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
1611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1631d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller    private void postOnCheckPasswordResult(final boolean success) {
1641d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller        // ensure this runs on UI thread
1651d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller        mLogin.post(new Runnable() {
1661d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller            public void run() {
1671d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                if (success) {
1681d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    // clear out forgotten password
1691d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    mLockPatternUtils.setPermanentlyLocked(false);
1701d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    mLockPatternUtils.setLockPatternEnabled(false);
1711d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    mLockPatternUtils.saveLockPattern(null);
1721d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller
1731d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    // launch the 'choose lock pattern' activity so
1741d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    // the user can pick a new one if they want to
1751d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    Intent intent = new Intent();
1761d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS);
1771d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1782c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani                    mContext.startActivityAsUser(intent,
1792c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani                            new UserHandle(mLockPatternUtils.getCurrentUser()));
1801d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    mCallback.reportSuccessfulUnlockAttempt();
1811d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller
182dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    // dismiss keyguard
183dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    mCallback.dismiss(true);
1841d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                } else {
1850a4f900463024908220d0c9bf4b291a6e1284846Adam Cohen                    mSecurityMessageDisplay.setMessage(R.string.kg_login_invalid_input, true);
1861d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    mPassword.setText("");
1871d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    mCallback.reportFailedUnlockAttempt();
1881d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                }
1891d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller            }
1901d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller        });
1911c01c8bc79941471857338bae011fd0a6790f89fFred Quintana    }
1921c01c8bc79941471857338bae011fd0a6790f89fFred Quintana
1931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
1941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public boolean dispatchKeyEvent(KeyEvent event) {
1951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (event.getAction() == KeyEvent.ACTION_DOWN
1961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
19784999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            if (mLockPatternUtils.isPermanentlyLocked()) {
198dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                mCallback.dismiss(false);
19984999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            } else {
200dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                // TODO: mCallback.forgotPattern(false);
20184999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            }
2021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
2031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return super.dispatchKeyEvent(event);
2051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
2081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Given the string the user entered in the 'username' field, find
2091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * the stored account that they probably intended.  Prefer, in order:
2101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *
2111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *   - an exact match for what was typed, or
2121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *   - a case-insensitive match for what was typed, or
2131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *   - if they didn't include a domain, an exact match of the username, or
2141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *   - if they didn't include a domain, a case-insensitive
2151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *     match of the username.
2161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *
2171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * If there is a tie for the best match, choose neither --
2181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * the user needs to be more specific.
2191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *
2201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return an account name from the database, or null if we can't
2211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * find a single best match.
2221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
2234e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintana    private Account findIntendedAccount(String username) {
2242c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani        Account[] accounts = AccountManager.get(mContext).getAccountsByTypeAsUser("com.google",
2252c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani                new UserHandle(mLockPatternUtils.getCurrentUser()));
2261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // Try to figure out which account they meant if they
2281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // typed only the username (and not the domain), or got
2291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // the case wrong.
2301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2314e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintana        Account bestAccount = null;
2321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        int bestScore = 0;
2334e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintana        for (Account a: accounts) {
2341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int score = 0;
2351c01c8bc79941471857338bae011fd0a6790f89fFred Quintana            if (username.equals(a.name)) {
2361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                score = 4;
2371c01c8bc79941471857338bae011fd0a6790f89fFred Quintana            } else if (username.equalsIgnoreCase(a.name)) {
2381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                score = 3;
2391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            } else if (username.indexOf('@') < 0) {
2401c01c8bc79941471857338bae011fd0a6790f89fFred Quintana                int i = a.name.indexOf('@');
2411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (i >= 0) {
2421c01c8bc79941471857338bae011fd0a6790f89fFred Quintana                    String aUsername = a.name.substring(0, i);
2431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    if (username.equals(aUsername)) {
2441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        score = 2;
2451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    } else if (username.equalsIgnoreCase(aUsername)) {
2461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        score = 1;
2471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    }
2481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
2491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (score > bestScore) {
2511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                bestAccount = a;
2521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                bestScore = score;
2531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            } else if (score == bestScore) {
2541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                bestAccount = null;
2551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return bestAccount;
2581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2601c01c8bc79941471857338bae011fd0a6790f89fFred Quintana    private void asyncCheckPassword() {
261dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mCallback.userActivity(AWAKE_POKE_MILLIS);
2621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final String login = mLogin.getText().toString();
2631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final String password = mPassword.getText().toString();
2644e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintana        Account account = findIntendedAccount(login);
2654e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintana        if (account == null) {
2661d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller            postOnCheckPasswordResult(false);
2671c01c8bc79941471857338bae011fd0a6790f89fFred Quintana            return;
268f29d580185e68bc23750d528511d2717d0de99aaFred Quintana        }
26984999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen        getProgressDialog().show();
270261259b673fbc86e4b04c458e12342f292e7a4f3Fred Quintana        Bundle options = new Bundle();
271261259b673fbc86e4b04c458e12342f292e7a4f3Fred Quintana        options.putString(AccountManager.KEY_PASSWORD, password);
2722c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani        AccountManager.get(mContext).confirmCredentialsAsUser(account, options, null /* activity */,
273261259b673fbc86e4b04c458e12342f292e7a4f3Fred Quintana                new AccountManagerCallback<Bundle>() {
274261259b673fbc86e4b04c458e12342f292e7a4f3Fred Quintana            public void run(AccountManagerFuture<Bundle> future) {
2751c01c8bc79941471857338bae011fd0a6790f89fFred Quintana                try {
276dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    mCallback.userActivity(AWAKE_POKE_MILLIS);
277261259b673fbc86e4b04c458e12342f292e7a4f3Fred Quintana                    final Bundle result = future.getResult();
278261259b673fbc86e4b04c458e12342f292e7a4f3Fred Quintana                    final boolean verified = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
2791d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    postOnCheckPasswordResult(verified);
2801c01c8bc79941471857338bae011fd0a6790f89fFred Quintana                } catch (OperationCanceledException e) {
2811d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    postOnCheckPasswordResult(false);
2821c01c8bc79941471857338bae011fd0a6790f89fFred Quintana                } catch (IOException e) {
2831d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    postOnCheckPasswordResult(false);
2841c01c8bc79941471857338bae011fd0a6790f89fFred Quintana                } catch (AuthenticatorException e) {
2851d587e3d5d91fab1cf3048bbeeafa86445cbd08cJim Miller                    postOnCheckPasswordResult(false);
28684999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                } finally {
28784999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                    mLogin.post(new Runnable() {
28884999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                        public void run() {
28984999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                            getProgressDialog().hide();
29084999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                        }
29184999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                    });
2921c01c8bc79941471857338bae011fd0a6790f89fFred Quintana                }
2931c01c8bc79941471857338bae011fd0a6790f89fFred Quintana            }
2942c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani        }, null /* handler */, new UserHandle(mLockPatternUtils.getCurrentUser()));
2951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
29684999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen
29784999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen    private Dialog getProgressDialog() {
29884999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen        if (mCheckingDialog == null) {
29984999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            mCheckingDialog = new ProgressDialog(mContext);
30084999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            mCheckingDialog.setMessage(
301dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    mContext.getString(R.string.kg_login_checking_password));
30284999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            mCheckingDialog.setIndeterminate(true);
30384999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            mCheckingDialog.setCancelable(false);
30484999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            mCheckingDialog.getWindow().setType(
30584999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
30684999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen        }
30784999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen        return mCheckingDialog;
30884999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen    }
309dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
310dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
311dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void onPause() {
312dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
313dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
314dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
315dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
316a042ac90640c0c3fd3c5349083b86bbfd6319b64Chris Wren    public void onResume(int reason) {
317dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        reset();
318dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
319dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
3200ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    @Override
3216fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen    public void showUsabilityHint() {
3226fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen    }
323c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren
324c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren    @Override
325c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren    public void showBouncer(int duration) {
326c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren    }
327c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren
328c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren    @Override
329c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren    public void hideBouncer(int duration) {
330c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren    }
3311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project}
332dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
333