1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/*
2afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
4afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * you may not use this file except in compliance with the License.
6afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * You may obtain a copy of the License at
7afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
8afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
10afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * See the License for the specific language governing permissions and
14afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * limitations under the License.
15afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
16afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
17afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpackage com.android.settings;
18afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
19afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.internal.widget.LockPatternUtils;
20afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.internal.widget.LockPatternView;
21afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
2256544d0e9198ab21dabec621cdf419b52b412dacJim Millerimport com.android.internal.widget.LockPatternView.Cell;
23afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.Activity;
2517e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.app.Fragment;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
27afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.CountDownTimer;
28afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.SystemClock;
29afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Bundle;
3017e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.preference.PreferenceActivity;
31afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.TextView;
3217e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.view.LayoutInflater;
3317e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.view.View;
3417e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.view.ViewGroup;
35afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
36afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.List;
37afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
38afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/**
39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Launch this when you want the user to confirm their lock pattern.
40afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
41afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Sets an activity result of {@link Activity#RESULT_OK} when the user
42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * successfully confirmed their pattern.
43afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
4417e9e1933055b207473b488595b2887bfcaea32eJim Millerpublic class ConfirmLockPattern extends PreferenceActivity {
45afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
46afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
47afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Names of {@link CharSequence} fields within the originating {@link Intent}
48afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * that are used to configure the keyguard confirmation view's labeling.
49afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * The view will use the system-defined resource strings for any labels that
50afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * the caller does not supply.
51afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
5217e9e1933055b207473b488595b2887bfcaea32eJim Miller    public static final String PACKAGE = "com.android.settings";
5317e9e1933055b207473b488595b2887bfcaea32eJim Miller    public static final String HEADER_TEXT = PACKAGE + ".ConfirmLockPattern.header";
5417e9e1933055b207473b488595b2887bfcaea32eJim Miller    public static final String FOOTER_TEXT = PACKAGE + ".ConfirmLockPattern.footer";
5517e9e1933055b207473b488595b2887bfcaea32eJim Miller    public static final String HEADER_WRONG_TEXT = PACKAGE + ".ConfirmLockPattern.header_wrong";
5617e9e1933055b207473b488595b2887bfcaea32eJim Miller    public static final String FOOTER_WRONG_TEXT = PACKAGE + ".ConfirmLockPattern.footer_wrong";
57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
58afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private enum Stage {
59afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        NeedToUnlock,
60afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        NeedToUnlockWrong,
61afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        LockedOut
62afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
63afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
64afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
658c74072e9cad7ae7cf7266f87b8f202aa42939ceJim Miller    public void onCreate(Bundle savedInstanceState) {
668c74072e9cad7ae7cf7266f87b8f202aa42939ceJim Miller        super.onCreate(savedInstanceState);
678c74072e9cad7ae7cf7266f87b8f202aa42939ceJim Miller        CharSequence msg = getText(R.string.lockpassword_confirm_your_pattern_header);
688c74072e9cad7ae7cf7266f87b8f202aa42939ceJim Miller        showBreadCrumbs(msg, msg);
698c74072e9cad7ae7cf7266f87b8f202aa42939ceJim Miller    }
708c74072e9cad7ae7cf7266f87b8f202aa42939ceJim Miller
718c74072e9cad7ae7cf7266f87b8f202aa42939ceJim Miller    @Override
7217e9e1933055b207473b488595b2887bfcaea32eJim Miller    public Intent getIntent() {
7317e9e1933055b207473b488595b2887bfcaea32eJim Miller        Intent modIntent = new Intent(super.getIntent());
7417e9e1933055b207473b488595b2887bfcaea32eJim Miller        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, ConfirmLockPatternFragment.class.getName());
7517e9e1933055b207473b488595b2887bfcaea32eJim Miller        modIntent.putExtra(EXTRA_NO_HEADERS, true);
7617e9e1933055b207473b488595b2887bfcaea32eJim Miller        return modIntent;
77afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
78afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
7917e9e1933055b207473b488595b2887bfcaea32eJim Miller    public static class ConfirmLockPatternFragment extends Fragment {
80afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
8117e9e1933055b207473b488595b2887bfcaea32eJim Miller        // how long we wait to clear a wrong pattern
8217e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
8317e9e1933055b207473b488595b2887bfcaea32eJim Miller
8417e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String KEY_NUM_WRONG_ATTEMPTS = "num_wrong_attempts";
8517e9e1933055b207473b488595b2887bfcaea32eJim Miller
8617e9e1933055b207473b488595b2887bfcaea32eJim Miller        private LockPatternView mLockPatternView;
8717e9e1933055b207473b488595b2887bfcaea32eJim Miller        private LockPatternUtils mLockPatternUtils;
8817e9e1933055b207473b488595b2887bfcaea32eJim Miller        private int mNumWrongConfirmAttempts;
8917e9e1933055b207473b488595b2887bfcaea32eJim Miller        private CountDownTimer mCountdownTimer;
9017e9e1933055b207473b488595b2887bfcaea32eJim Miller
9117e9e1933055b207473b488595b2887bfcaea32eJim Miller        private TextView mHeaderTextView;
9217e9e1933055b207473b488595b2887bfcaea32eJim Miller        private TextView mFooterTextView;
9317e9e1933055b207473b488595b2887bfcaea32eJim Miller
9417e9e1933055b207473b488595b2887bfcaea32eJim Miller        // caller-supplied text for various prompts
9517e9e1933055b207473b488595b2887bfcaea32eJim Miller        private CharSequence mHeaderText;
9617e9e1933055b207473b488595b2887bfcaea32eJim Miller        private CharSequence mFooterText;
9717e9e1933055b207473b488595b2887bfcaea32eJim Miller        private CharSequence mHeaderWrongText;
9817e9e1933055b207473b488595b2887bfcaea32eJim Miller        private CharSequence mFooterWrongText;
9917e9e1933055b207473b488595b2887bfcaea32eJim Miller
10017e9e1933055b207473b488595b2887bfcaea32eJim Miller        // required constructor for fragments
10117e9e1933055b207473b488595b2887bfcaea32eJim Miller        public ConfirmLockPatternFragment() {
102afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
103afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
104afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
10517e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
10617e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onCreate(Bundle savedInstanceState) {
10717e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onCreate(savedInstanceState);
10817e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternUtils = new LockPatternUtils(getActivity());
109afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
110afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
11117e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
11217e9e1933055b207473b488595b2887bfcaea32eJim Miller        public View onCreateView(LayoutInflater inflater, ViewGroup container,
11317e9e1933055b207473b488595b2887bfcaea32eJim Miller                Bundle savedInstanceState) {
11417e9e1933055b207473b488595b2887bfcaea32eJim Miller            View view = inflater.inflate(R.layout.confirm_lock_pattern, null);
11517e9e1933055b207473b488595b2887bfcaea32eJim Miller            mHeaderTextView = (TextView) view.findViewById(R.id.headerText);
11617e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern);
11717e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterTextView = (TextView) view.findViewById(R.id.footerText);
11817e9e1933055b207473b488595b2887bfcaea32eJim Miller
11917e9e1933055b207473b488595b2887bfcaea32eJim Miller            // make it so unhandled touch events within the unlock screen go to the
12017e9e1933055b207473b488595b2887bfcaea32eJim Miller            // lock pattern view.
12117e9e1933055b207473b488595b2887bfcaea32eJim Miller            final LinearLayoutWithDefaultTouchRecepient topLayout
12217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    = (LinearLayoutWithDefaultTouchRecepient) view.findViewById(R.id.topLayout);
12317e9e1933055b207473b488595b2887bfcaea32eJim Miller            topLayout.setDefaultTouchRecepient(mLockPatternView);
12417e9e1933055b207473b488595b2887bfcaea32eJim Miller
12517e9e1933055b207473b488595b2887bfcaea32eJim Miller            Intent intent = getActivity().getIntent();
12617e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (intent != null) {
12717e9e1933055b207473b488595b2887bfcaea32eJim Miller                mHeaderText = intent.getCharSequenceExtra(HEADER_TEXT);
12817e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterText = intent.getCharSequenceExtra(FOOTER_TEXT);
12917e9e1933055b207473b488595b2887bfcaea32eJim Miller                mHeaderWrongText = intent.getCharSequenceExtra(HEADER_WRONG_TEXT);
13017e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterWrongText = intent.getCharSequenceExtra(FOOTER_WRONG_TEXT);
13117e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
132afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
13317e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
13417e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.setOnPatternListener(mConfirmExistingLockPatternListener);
13517e9e1933055b207473b488595b2887bfcaea32eJim Miller            updateStage(Stage.NeedToUnlock);
13647d380f1e6c823cea444004cb799d4c791145cc6Jim Miller
13717e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (savedInstanceState != null) {
13817e9e1933055b207473b488595b2887bfcaea32eJim Miller                mNumWrongConfirmAttempts = savedInstanceState.getInt(KEY_NUM_WRONG_ATTEMPTS);
13917e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
14017e9e1933055b207473b488595b2887bfcaea32eJim Miller                // on first launch, if no lock pattern is set, then finish with
14117e9e1933055b207473b488595b2887bfcaea32eJim Miller                // success (don't want user to get stuck confirming something that
14217e9e1933055b207473b488595b2887bfcaea32eJim Miller                // doesn't exist).
14317e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (!mLockPatternUtils.savedPatternExists()) {
14417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    getActivity().setResult(Activity.RESULT_OK);
14517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    getActivity().finish();
146afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
14717e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
14817e9e1933055b207473b488595b2887bfcaea32eJim Miller            return view;
149afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
150afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
15117e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
15217e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onSaveInstanceState(Bundle outState) {
15317e9e1933055b207473b488595b2887bfcaea32eJim Miller            // deliberately not calling super since we are managing this in full
15417e9e1933055b207473b488595b2887bfcaea32eJim Miller            outState.putInt(KEY_NUM_WRONG_ATTEMPTS, mNumWrongConfirmAttempts);
155afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
156afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
15717e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
15817e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onPause() {
15917e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onPause();
160afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
16117e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (mCountdownTimer != null) {
16217e9e1933055b207473b488595b2887bfcaea32eJim Miller                mCountdownTimer.cancel();
16317e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
16417e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
165afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
16617e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
16717e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onResume() {
16817e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onResume();
16917e9e1933055b207473b488595b2887bfcaea32eJim Miller
17017e9e1933055b207473b488595b2887bfcaea32eJim Miller            // if the user is currently locked out, enforce it.
17117e9e1933055b207473b488595b2887bfcaea32eJim Miller            long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
17217e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (deadline != 0) {
17317e9e1933055b207473b488595b2887bfcaea32eJim Miller                handleAttemptLockout(deadline);
17417e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else if (!mLockPatternView.isEnabled()) {
17517e9e1933055b207473b488595b2887bfcaea32eJim Miller                // The deadline has passed, but the timer was cancelled...
17617e9e1933055b207473b488595b2887bfcaea32eJim Miller                // Need to clean up.
17717e9e1933055b207473b488595b2887bfcaea32eJim Miller                mNumWrongConfirmAttempts = 0;
17817e9e1933055b207473b488595b2887bfcaea32eJim Miller                updateStage(Stage.NeedToUnlock);
17917e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
180afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
181afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
18217e9e1933055b207473b488595b2887bfcaea32eJim Miller        private void updateStage(Stage stage) {
18317e9e1933055b207473b488595b2887bfcaea32eJim Miller            switch (stage) {
18417e9e1933055b207473b488595b2887bfcaea32eJim Miller                case NeedToUnlock:
18517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (mHeaderText != null) {
18617e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mHeaderTextView.setText(mHeaderText);
18717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else {
18817e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mHeaderTextView.setText(R.string.lockpattern_need_to_unlock);
18917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
19017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (mFooterText != null) {
19117e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mFooterTextView.setText(mFooterText);
19217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else {
19317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mFooterTextView.setText(R.string.lockpattern_need_to_unlock_footer);
19417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
19517e9e1933055b207473b488595b2887bfcaea32eJim Miller
19617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.setEnabled(true);
19717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.enableInput();
19817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
19917e9e1933055b207473b488595b2887bfcaea32eJim Miller                case NeedToUnlockWrong:
20017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (mHeaderWrongText != null) {
20117e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mHeaderTextView.setText(mHeaderWrongText);
20217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else {
20317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mHeaderTextView.setText(R.string.lockpattern_need_to_unlock_wrong);
20417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
20517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (mFooterWrongText != null) {
20617e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mFooterTextView.setText(mFooterWrongText);
20717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else {
20817e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mFooterTextView.setText(R.string.lockpattern_need_to_unlock_wrong_footer);
20917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
21017e9e1933055b207473b488595b2887bfcaea32eJim Miller
21117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
21217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.setEnabled(true);
21317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.enableInput();
21417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
21517e9e1933055b207473b488595b2887bfcaea32eJim Miller                case LockedOut:
21617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.clearPattern();
21717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    // enabled = false means: disable input, and have the
21817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    // appearance of being disabled.
21917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.setEnabled(false); // appearance of being disabled
22017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
22117e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
222eef72c39ae83697b1beaa148ec56aced67382fecalanv
223eef72c39ae83697b1beaa148ec56aced67382fecalanv            // Always announce the header for accessibility. This is a no-op
224eef72c39ae83697b1beaa148ec56aced67382fecalanv            // when accessibility is disabled.
225eef72c39ae83697b1beaa148ec56aced67382fecalanv            mHeaderTextView.announceForAccessibility(mHeaderTextView.getText());
226afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
227afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
22817e9e1933055b207473b488595b2887bfcaea32eJim Miller        private Runnable mClearPatternRunnable = new Runnable() {
22917e9e1933055b207473b488595b2887bfcaea32eJim Miller            public void run() {
23017e9e1933055b207473b488595b2887bfcaea32eJim Miller                mLockPatternView.clearPattern();
23117e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
23217e9e1933055b207473b488595b2887bfcaea32eJim Miller        };
23356544d0e9198ab21dabec621cdf419b52b412dacJim Miller
23417e9e1933055b207473b488595b2887bfcaea32eJim Miller        // clear the wrong pattern unless they have started a new one
23517e9e1933055b207473b488595b2887bfcaea32eJim Miller        // already
23617e9e1933055b207473b488595b2887bfcaea32eJim Miller        private void postClearPatternRunnable() {
23717e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.removeCallbacks(mClearPatternRunnable);
23817e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
23956544d0e9198ab21dabec621cdf419b52b412dacJim Miller        }
24056544d0e9198ab21dabec621cdf419b52b412dacJim Miller
24117e9e1933055b207473b488595b2887bfcaea32eJim Miller        /**
24217e9e1933055b207473b488595b2887bfcaea32eJim Miller         * The pattern listener that responds according to a user confirming
24317e9e1933055b207473b488595b2887bfcaea32eJim Miller         * an existing lock pattern.
24417e9e1933055b207473b488595b2887bfcaea32eJim Miller         */
24517e9e1933055b207473b488595b2887bfcaea32eJim Miller        private LockPatternView.OnPatternListener mConfirmExistingLockPatternListener
24617e9e1933055b207473b488595b2887bfcaea32eJim Miller                = new LockPatternView.OnPatternListener()  {
24717e9e1933055b207473b488595b2887bfcaea32eJim Miller
24817e9e1933055b207473b488595b2887bfcaea32eJim Miller            public void onPatternStart() {
24917e9e1933055b207473b488595b2887bfcaea32eJim Miller                mLockPatternView.removeCallbacks(mClearPatternRunnable);
250afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
25117e9e1933055b207473b488595b2887bfcaea32eJim Miller
25217e9e1933055b207473b488595b2887bfcaea32eJim Miller            public void onPatternCleared() {
25317e9e1933055b207473b488595b2887bfcaea32eJim Miller                mLockPatternView.removeCallbacks(mClearPatternRunnable);
254afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
255afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
25617e9e1933055b207473b488595b2887bfcaea32eJim Miller            public void onPatternCellAdded(List<Cell> pattern) {
25717e9e1933055b207473b488595b2887bfcaea32eJim Miller
258afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
25917e9e1933055b207473b488595b2887bfcaea32eJim Miller
26017e9e1933055b207473b488595b2887bfcaea32eJim Miller            public void onPatternDetected(List<LockPatternView.Cell> pattern) {
26117e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (mLockPatternUtils.checkPattern(pattern)) {
2620e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom
2630e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom                    Intent intent = new Intent();
2640e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom                    intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
2650e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom                                    LockPatternUtils.patternToString(pattern));
2660e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom
2670e88f4dd19a80e9e4d759595439773fb3e1f0c50Brian Carlstrom                    getActivity().setResult(Activity.RESULT_OK, intent);
26817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    getActivity().finish();
26917e9e1933055b207473b488595b2887bfcaea32eJim Miller                } else {
27017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL &&
27117e9e1933055b207473b488595b2887bfcaea32eJim Miller                            ++mNumWrongConfirmAttempts
27217e9e1933055b207473b488595b2887bfcaea32eJim Miller                            >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
27317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
27417e9e1933055b207473b488595b2887bfcaea32eJim Miller                        handleAttemptLockout(deadline);
27517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else {
27617e9e1933055b207473b488595b2887bfcaea32eJim Miller                        updateStage(Stage.NeedToUnlockWrong);
27717e9e1933055b207473b488595b2887bfcaea32eJim Miller                        postClearPatternRunnable();
27817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
27917e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
28017e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
28117e9e1933055b207473b488595b2887bfcaea32eJim Miller        };
28217e9e1933055b207473b488595b2887bfcaea32eJim Miller
28317e9e1933055b207473b488595b2887bfcaea32eJim Miller
28417e9e1933055b207473b488595b2887bfcaea32eJim Miller        private void handleAttemptLockout(long elapsedRealtimeDeadline) {
28517e9e1933055b207473b488595b2887bfcaea32eJim Miller            updateStage(Stage.LockedOut);
28617e9e1933055b207473b488595b2887bfcaea32eJim Miller            long elapsedRealtime = SystemClock.elapsedRealtime();
28717e9e1933055b207473b488595b2887bfcaea32eJim Miller            mCountdownTimer = new CountDownTimer(
28817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    elapsedRealtimeDeadline - elapsedRealtime,
28917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LockPatternUtils.FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS) {
29017e9e1933055b207473b488595b2887bfcaea32eJim Miller
29117e9e1933055b207473b488595b2887bfcaea32eJim Miller                @Override
29217e9e1933055b207473b488595b2887bfcaea32eJim Miller                public void onTick(long millisUntilFinished) {
29317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mHeaderTextView.setText(R.string.lockpattern_too_many_failed_confirmation_attempts_header);
29417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    final int secondsCountdown = (int) (millisUntilFinished / 1000);
29517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mFooterTextView.setText(getString(
29617e9e1933055b207473b488595b2887bfcaea32eJim Miller                            R.string.lockpattern_too_many_failed_confirmation_attempts_footer,
29717e9e1933055b207473b488595b2887bfcaea32eJim Miller                            secondsCountdown));
29817e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
29917e9e1933055b207473b488595b2887bfcaea32eJim Miller
30017e9e1933055b207473b488595b2887bfcaea32eJim Miller                @Override
30117e9e1933055b207473b488595b2887bfcaea32eJim Miller                public void onFinish() {
30217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mNumWrongConfirmAttempts = 0;
30317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    updateStage(Stage.NeedToUnlock);
30417e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
30517e9e1933055b207473b488595b2887bfcaea32eJim Miller            }.start();
30617e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
307afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
308afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
309