ChooseLockPattern.java revision bbb4afa19f75694c585506b0c091372d60e07ca7
1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/*
2afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Copyright (C) 2007 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.google.android.collect.Lists;
20afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
21afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
22afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.internal.widget.LockPatternUtils;
23afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.internal.widget.LockPatternView;
2456544d0e9198ab21dabec621cdf419b52b412dacJim Millerimport com.android.internal.widget.LockPatternView.Cell;
25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport static com.android.internal.widget.LockPatternView.DisplayMode;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
27afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.Activity;
28afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
29afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Bundle;
30afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.KeyEvent;
31afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.View;
32afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.Window;
33afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.TextView;
34afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
35afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.ArrayList;
36afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.Collections;
37afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.List;
38afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/**
40afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * If the user has a lock pattern set already, makes them confirm the existing one.
41afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Then, prompts the user to choose a lock pattern:
43afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * - prompts for initial pattern
44afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * - asks for confirmation / restart
45afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * - saves chosen password when confirmed
46afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
47afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpublic class ChooseLockPattern extends Activity implements View.OnClickListener{
48afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
49afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Used by the choose lock pattern wizard to indicate the wizard is
50afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * finished, and each activity in the wizard should finish.
51afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * <p>
52afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Previously, each activity in the wizard would finish itself after
53afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * starting the next activity. However, this leads to broken 'Back'
54afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * behavior. So, now an activity does not finish itself until it gets this
55afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * result.
56afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    static final int RESULT_FINISHED = RESULT_FIRST_USER;
5800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
5900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller    public static final int CONFIRM_EXISTING_REQUEST = 55;
6000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
61afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // how long after a confirmation message is shown before moving on
62afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    static final int INFORMATION_MSG_TIMEOUT_MS = 3000;
63afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
64afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // how long we wait to clear a wrong pattern
65afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
66afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
67afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int ID_EMPTY_MESSAGE = -1;
68afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
69afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected TextView mHeaderText;
70afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected LockPatternView mLockPatternView;
71afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected TextView mFooterText;
72afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private TextView mFooterLeftButton;
73afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private TextView mFooterRightButton;
74afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected List<LockPatternView.Cell> mChosenPattern = null;
75afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
76afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
77afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * The patten used during the help screen to show how to draw a pattern.
78afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
79afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private final List<LockPatternView.Cell> mAnimatePattern =
8000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller            Collections.unmodifiableList(Lists.newArrayList(
8100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                    LockPatternView.Cell.of(0, 0),
8200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                    LockPatternView.Cell.of(0, 1),
8300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                    LockPatternView.Cell.of(1, 1),
8400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                    LockPatternView.Cell.of(2, 1)
8500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller            ));
86afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
8700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller    @Override
8800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller    protected void onActivityResult(int requestCode, int resultCode,
8900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller            Intent data) {
9000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller        super.onActivityResult(requestCode, resultCode, data);
9100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller        switch (requestCode) {
9200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller            case CONFIRM_EXISTING_REQUEST:
9300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                if (resultCode != Activity.RESULT_OK) {
9400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                    setResult(RESULT_FINISHED);
9500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                    finish();
9600d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                }
9700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                updateStage(Stage.Introduction);
9800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                break;
9900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller        }
10000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller    }
101afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
102afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
103afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * The pattern listener that responds according to a user choosing a new
104afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * lock pattern.
105afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
106afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected LockPatternView.OnPatternListener mChooseNewLockPatternListener = new LockPatternView.OnPatternListener() {
107afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
108afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            public void onPatternStart() {
109afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLockPatternView.removeCallbacks(mClearPatternRunnable);
110afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                patternInProgress();
111afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
112afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
113afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            public void onPatternCleared() {
114afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLockPatternView.removeCallbacks(mClearPatternRunnable);
115afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
116afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
117afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            public void onPatternDetected(List<LockPatternView.Cell> pattern) {
118afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (mUiStage == Stage.NeedToConfirm || mUiStage == Stage.ConfirmWrong) {
119afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    if (mChosenPattern == null) throw new IllegalStateException("null chosen pattern in stage 'need to confirm");
120afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    if (mChosenPattern.equals(pattern)) {
121afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        updateStage(Stage.ChoiceConfirmed);
122afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    } else {
123afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        updateStage(Stage.ConfirmWrong);
124afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    }
125afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                } else if (mUiStage == Stage.Introduction || mUiStage == Stage.ChoiceTooShort){
126afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    if (pattern.size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
127afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        updateStage(Stage.ChoiceTooShort);
128afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    } else {
129afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        mChosenPattern = new ArrayList<LockPatternView.Cell>(pattern);
130afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        updateStage(Stage.FirstChoiceValid);
131afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    }
132afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                } else {
133afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    throw new IllegalStateException("Unexpected stage " + mUiStage + " when "
134afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                            + "entering the pattern.");
135afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
136afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
137afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
13800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller            public void onPatternCellAdded(List<Cell> pattern) {
13956544d0e9198ab21dabec621cdf419b52b412dacJim Miller
14056544d0e9198ab21dabec621cdf419b52b412dacJim Miller            }
14156544d0e9198ab21dabec621cdf419b52b412dacJim Miller
142afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            private void patternInProgress() {
143afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mHeaderText.setText(R.string.lockpattern_recording_inprogress);
144afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mFooterText.setText("");
145afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mFooterLeftButton.setEnabled(false);
146afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mFooterRightButton.setEnabled(false);
147afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
148afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     };
149afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
150afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
151afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
152afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * The states of the left footer button.
153afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
154afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    enum LeftButtonMode {
155afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Cancel(R.string.cancel, true),
156afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        CancelDisabled(R.string.cancel, false),
157afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Retry(R.string.lockpattern_retry_button_text, true),
158afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        RetryDisabled(R.string.lockpattern_retry_button_text, false),
159afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Gone(ID_EMPTY_MESSAGE, false);
160afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
161afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
162afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /**
163afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * @param text The displayed text for this mode.
164afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * @param enabled Whether the button should be enabled.
165afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
166afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        LeftButtonMode(int text, boolean enabled) {
167afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            this.text = text;
168afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            this.enabled = enabled;
169afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
170afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
171afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        final int text;
172afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        final boolean enabled;
173afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
174afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
175afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
176afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * The states of the right button.
177afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
178afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    enum RightButtonMode {
179afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Continue(R.string.lockpattern_continue_button_text, true),
180afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ContinueDisabled(R.string.lockpattern_continue_button_text, false),
181afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Confirm(R.string.lockpattern_confirm_button_text, true),
182afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ConfirmDisabled(R.string.lockpattern_confirm_button_text, false),
183afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Ok(android.R.string.ok, true);
184afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
185afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /**
186afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * @param text The displayed text for this mode.
187afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * @param enabled Whether the button should be enabled.
188afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
189afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        RightButtonMode(int text, boolean enabled) {
190afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            this.text = text;
191afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            this.enabled = enabled;
192afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
193afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
194afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        final int text;
195afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        final boolean enabled;
196afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
197afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
198afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
199afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Keep track internally of where the user is in choosing a pattern.
200afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
201afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected enum Stage {
202afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
203afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Introduction(
204afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.lockpattern_recording_intro_header,
205afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LeftButtonMode.Cancel, RightButtonMode.ContinueDisabled,
206afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.lockpattern_recording_intro_footer, true),
207afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        HelpScreen(
208afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.lockpattern_settings_help_how_to_record,
209afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LeftButtonMode.Gone, RightButtonMode.Ok, ID_EMPTY_MESSAGE, false),
210afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ChoiceTooShort(
211afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.lockpattern_recording_incorrect_too_short,
212afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LeftButtonMode.Retry, RightButtonMode.ContinueDisabled,
213afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                ID_EMPTY_MESSAGE, true),
214afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        FirstChoiceValid(
215afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.lockpattern_pattern_entered_header,
216afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LeftButtonMode.Retry, RightButtonMode.Continue, ID_EMPTY_MESSAGE, false),
217afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        NeedToConfirm(
218afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.lockpattern_need_to_confirm,
219afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LeftButtonMode.CancelDisabled, RightButtonMode.ConfirmDisabled,
220afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                ID_EMPTY_MESSAGE, true),
221afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ConfirmWrong(
222afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.lockpattern_need_to_unlock_wrong,
223afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
224afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                ID_EMPTY_MESSAGE, true),
225afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ChoiceConfirmed(
226afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.lockpattern_pattern_confirmed_header,
227afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LeftButtonMode.Cancel, RightButtonMode.Confirm, ID_EMPTY_MESSAGE, false);
228afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
229afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
230afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /**
231afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * @param headerMessage The message displayed at the top.
232afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * @param leftMode The mode of the left button.
233afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * @param rightMode The mode of the right button.
234afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * @param footerMessage The footer message.
235afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * @param patternEnabled Whether the pattern widget is enabled.
236afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
237afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Stage(int headerMessage,
238afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LeftButtonMode leftMode,
239afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                RightButtonMode rightMode,
240afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                int footerMessage, boolean patternEnabled) {
241afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            this.headerMessage = headerMessage;
242afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            this.leftMode = leftMode;
243afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            this.rightMode = rightMode;
244afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            this.footerMessage = footerMessage;
245afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            this.patternEnabled = patternEnabled;
246afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
247afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
248afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        final int headerMessage;
249afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        final LeftButtonMode leftMode;
250afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        final RightButtonMode rightMode;
251afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        final int footerMessage;
252afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        final boolean patternEnabled;
253afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
254afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
255afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private Stage mUiStage = Stage.Introduction;
256afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
257afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private Runnable mClearPatternRunnable = new Runnable() {
258afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public void run() {
259afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mLockPatternView.clearPattern();
260afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
261afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    };
262afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
26300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller    private ChooseLockSettingsHelper mChooseLockSettingsHelper;
26400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
265afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String KEY_UI_STAGE = "uiStage";
266afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String KEY_PATTERN_CHOICE = "chosenPattern";
267afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
268afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
269afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void onCreate(Bundle savedInstanceState) {
270afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onCreate(savedInstanceState);
27100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller        mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this);
272afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        requestWindowFeature(Window.FEATURE_NO_TITLE);
273afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
274afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        setupViews();
27500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
276afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // make it so unhandled touch events within the unlock screen go to the
277afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // lock pattern view.
278afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        final LinearLayoutWithDefaultTouchRecepient topLayout
279afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                = (LinearLayoutWithDefaultTouchRecepient) findViewById(
280afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.id.topLayout);
281afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        topLayout.setDefaultTouchRecepient(mLockPatternView);
282afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
283bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller        final boolean confirmCredentials = getIntent().getBooleanExtra("confirm_credentials", true);
284bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
285afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (savedInstanceState == null) {
286bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller            if (confirmCredentials) {
287bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                // first launch. As a security measure, we're in NeedToConfirm mode until we know
288bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                // there isn't an existing password or the user confirms their password.
289bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                updateStage(Stage.NeedToConfirm);
290bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                boolean launchedConfirmationActivity =
291bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                    mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST);
292bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                if (!launchedConfirmationActivity) {
293bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                    updateStage(Stage.Introduction);
294bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                }
295bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller            } else {
29600d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                updateStage(Stage.Introduction);
29700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller            }
298afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
299afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // restore from previous state
300afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE);
301afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (patternString != null) {
302afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mChosenPattern = LockPatternUtils.stringToPattern(patternString);
303afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
304afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
305afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
306afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
30700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
308afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
309afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Keep all "find view" related stuff confined to this function since in
310afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * case someone needs to subclass and customize.
311afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
312afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void setupViews() {
313afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        setContentView(R.layout.choose_lock_pattern);
31400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
315afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mHeaderText = (TextView) findViewById(R.id.headerText);
316afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
317afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
318afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
31900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller        mLockPatternView.setTactileFeedbackEnabled(
32000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller                mChooseLockSettingsHelper.utils().isTactileFeedbackEnabled());
321afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
322afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mFooterText = (TextView) findViewById(R.id.footerText);
323afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
324afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mFooterLeftButton = (TextView) findViewById(R.id.footerLeftButton);
325afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mFooterRightButton = (TextView) findViewById(R.id.footerRightButton);
326afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
327afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mFooterLeftButton.setOnClickListener(this);
328afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mFooterRightButton.setOnClickListener(this);
329afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
330afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
331afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onClick(View v) {
332afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (v == mFooterLeftButton) {
333afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (mUiStage.leftMode == LeftButtonMode.Retry) {
334afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mChosenPattern = null;
335afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLockPatternView.clearPattern();
336afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                updateStage(Stage.Introduction);
337afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } else if (mUiStage.leftMode == LeftButtonMode.Cancel) {
338afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // They are canceling the entire wizard
339afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                setResult(RESULT_FINISHED);
340afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                finish();
341afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } else {
342afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                throw new IllegalStateException("left footer button pressed, but stage of " +
343afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    mUiStage + " doesn't make sense");
344afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
345afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (v == mFooterRightButton) {
346afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
347afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (mUiStage.rightMode == RightButtonMode.Continue) {
348afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (mUiStage != Stage.FirstChoiceValid) {
349afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    throw new IllegalStateException("expected ui stage " + Stage.FirstChoiceValid
350afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                            + " when button is " + RightButtonMode.Continue);
351afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
352afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                updateStage(Stage.NeedToConfirm);
353afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } else if (mUiStage.rightMode == RightButtonMode.Confirm) {
354afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (mUiStage != Stage.ChoiceConfirmed) {
355afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    throw new IllegalStateException("expected ui stage " + Stage.ChoiceConfirmed
356afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                            + " when button is " + RightButtonMode.Confirm);
357afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
358afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                saveChosenPatternAndFinish();
359afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } else if (mUiStage.rightMode == RightButtonMode.Ok) {
360afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (mUiStage != Stage.HelpScreen) {
361afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    throw new IllegalStateException("Help screen is only mode with ok button, but " +
362afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                            "stage is " + mUiStage);
363afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
364afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLockPatternView.clearPattern();
365afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLockPatternView.setDisplayMode(DisplayMode.Correct);
366afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                updateStage(Stage.Introduction);
367afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
368afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
369afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
370afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
371afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
372afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
373afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
374afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (mUiStage == Stage.HelpScreen) {
375afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                updateStage(Stage.Introduction);
376afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return true;
377afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
378afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
379afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_MENU && mUiStage == Stage.Introduction) {
380afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            updateStage(Stage.HelpScreen);
381afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return true;
382afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
383afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
384afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return super.onKeyDown(keyCode, event);
385afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
386afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
387afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
388afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void onSaveInstanceState(Bundle outState) {
389afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onSaveInstanceState(outState);
390afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
391afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
392afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mChosenPattern != null) {
393afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            outState.putString(KEY_PATTERN_CHOICE, LockPatternUtils.patternToString(mChosenPattern));
394afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
395afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
396afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
397afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
398afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
399afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Updates the messages and buttons appropriate to what stage the user
400afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * is at in choosing a view.  This doesn't handle clearing out the pattern;
401afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * the pattern is expected to be in the right state.
402afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * @param stage
403afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
404afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void updateStage(Stage stage) {
405afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
406afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mUiStage = stage;
407afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
40800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller        // header text, footer text, visibility and
409afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // enabled state all known from the stage
410afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (stage == Stage.ChoiceTooShort) {
411afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mHeaderText.setText(
412afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    getResources().getString(
413afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                            stage.headerMessage,
414afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                            LockPatternUtils.MIN_LOCK_PATTERN_SIZE));
415afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
416afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mHeaderText.setText(stage.headerMessage);
417afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
418afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (stage.footerMessage == ID_EMPTY_MESSAGE) {
419afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mFooterText.setText("");
420afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
421afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mFooterText.setText(stage.footerMessage);
422afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
423afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
424afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (stage.leftMode == LeftButtonMode.Gone) {
425afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mFooterLeftButton.setVisibility(View.GONE);
426afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
427afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mFooterLeftButton.setVisibility(View.VISIBLE);
428afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mFooterLeftButton.setText(stage.leftMode.text);
429afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mFooterLeftButton.setEnabled(stage.leftMode.enabled);
430afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
431afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
432afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mFooterRightButton.setText(stage.rightMode.text);
433afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mFooterRightButton.setEnabled(stage.rightMode.enabled);
434afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
435afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // same for whether the patten is enabled
436afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (stage.patternEnabled) {
437afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mLockPatternView.enableInput();
438afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
439afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mLockPatternView.disableInput();
440afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
441afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
442afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // the rest of the stuff varies enough that it is easier just to handle
443afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // on a case by case basis.
444afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mLockPatternView.setDisplayMode(DisplayMode.Correct);
445afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
446afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        switch (mUiStage) {
447afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case Introduction:
448afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLockPatternView.clearPattern();
449afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
450afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case HelpScreen:
451afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLockPatternView.setPattern(DisplayMode.Animate, mAnimatePattern);
452afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
453afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case ChoiceTooShort:
454afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLockPatternView.setDisplayMode(DisplayMode.Wrong);
455afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                postClearPatternRunnable();
456afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
457afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case FirstChoiceValid:
458afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
459afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case NeedToConfirm:
460afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLockPatternView.clearPattern();
461afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
462afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case ConfirmWrong:
463afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLockPatternView.setDisplayMode(DisplayMode.Wrong);
464afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                postClearPatternRunnable();
465afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
466afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case ChoiceConfirmed:
467afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
468afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
469afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
470afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
471afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
472afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // clear the wrong pattern unless they have started a new one
473afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    // already
474afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void postClearPatternRunnable() {
475afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mLockPatternView.removeCallbacks(mClearPatternRunnable);
476afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
477afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
478afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
479afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void saveChosenPatternAndFinish() {
48000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller        LockPatternUtils utils = mChooseLockSettingsHelper.utils();
48100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller        final boolean lockVirgin = !utils.isPatternEverChosen();
482e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
48300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller        utils.saveLockPattern(mChosenPattern);
48400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller        utils.setLockPatternEnabled(true);
485e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
486e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        if (lockVirgin) {
48700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller            utils.setVisiblePatternEnabled(true);
48800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller            utils.setTactileFeedbackEnabled(false);
489e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
49000d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
491afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        setResult(RESULT_FINISHED);
492afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        finish();
493afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
494afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
495