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
172eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lampackage com.android.settings.password;
18afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
19afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.Activity;
2017e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.app.Fragment;
210698a216311acd9ab52224602d1a75c08bf89f04Jim Millerimport android.content.Context;
22afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
239990f397220703f4d2c922560a8e29e60bcce39fMaurice Lamimport android.content.res.Resources.Theme;
24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Bundle;
2591e6c499ca8f33cc093fed4277d2b48ab780b309Andres Moralesimport android.util.Log;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.KeyEvent;
2717e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.view.LayoutInflater;
28afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.View;
2917e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.view.ViewGroup;
30d189ac52a4e49291b729d817fc903116abc086d0Maurice Lamimport android.widget.LinearLayout;
31011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyuleiimport android.widget.ScrollView;
32afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.TextView;
33afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
34265d3c2a0c36251bf8a9f571d7239b6dd404d942Tamas Berghammerimport com.android.internal.logging.nano.MetricsProto.MetricsEvent;
3539b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
3639b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternUtils;
3739b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternUtils.RequestThrottledException;
3839b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternView;
3939b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternView.Cell;
4039b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternView.DisplayMode;
412eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.EncryptionInterstitial;
422eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.R;
432eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.SettingsActivity;
449990f397220703f4d2c922560a8e29e60bcce39fMaurice Lamimport com.android.settings.SetupWizardUtils;
452eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.Utils;
462d0b3447360666847c483e6ce2521846c66c25c1Fan Zhangimport com.android.settings.core.InstrumentedPreferenceFragment;
4739b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.settings.notification.RedactionInterstitial;
48d189ac52a4e49291b729d817fc903116abc086d0Maurice Lamimport com.android.setupwizardlib.GlifLayout;
492eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam
5039b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.google.android.collect.Lists;
5139b467482d1bf256a111c757e9b7621c6f523271Jason Monk
52afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.ArrayList;
53afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.Collections;
54afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.List;
55afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
56afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/**
57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * If the user has a lock pattern set already, makes them confirm the existing one.
58afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
59afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Then, prompts the user to choose a lock pattern:
60afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * - prompts for initial pattern
61afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * - asks for confirmation / restart
62afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * - saves chosen password when confirmed
63afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
64263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Megliopublic class ChooseLockPattern extends SettingsActivity {
65afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
66afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Used by the choose lock pattern wizard to indicate the wizard is
67afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * finished, and each activity in the wizard should finish.
68afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * <p>
69afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Previously, each activity in the wizard would finish itself after
70afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * starting the next activity. However, this leads to broken 'Back'
71afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * behavior. So, now an activity does not finish itself until it gets this
72afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * result.
73afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
74afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    static final int RESULT_FINISHED = RESULT_FIRST_USER;
7500d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
7691e6c499ca8f33cc093fed4277d2b48ab780b309Andres Morales    private static final String TAG = "ChooseLockPattern";
7791e6c499ca8f33cc093fed4277d2b48ab780b309Andres Morales
7817e9e1933055b207473b488595b2887bfcaea32eJim Miller    @Override
7917e9e1933055b207473b488595b2887bfcaea32eJim Miller    public Intent getIntent() {
8017e9e1933055b207473b488595b2887bfcaea32eJim Miller        Intent modIntent = new Intent(super.getIntent());
816b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
8217e9e1933055b207473b488595b2887bfcaea32eJim Miller        return modIntent;
8317e9e1933055b207473b488595b2887bfcaea32eJim Miller    }
8400d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
859990f397220703f4d2c922560a8e29e60bcce39fMaurice Lam    @Override
869990f397220703f4d2c922560a8e29e60bcce39fMaurice Lam    protected void onApplyThemeResource(Theme theme, int resid, boolean first) {
879990f397220703f4d2c922560a8e29e60bcce39fMaurice Lam        resid = SetupWizardUtils.getTheme(getIntent());
889990f397220703f4d2c922560a8e29e60bcce39fMaurice Lam        super.onApplyThemeResource(theme, resid, first);
899990f397220703f4d2c922560a8e29e60bcce39fMaurice Lam    }
909990f397220703f4d2c922560a8e29e60bcce39fMaurice Lam
912eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam    public static class IntentBuilder {
922eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        private final Intent mIntent;
930698a216311acd9ab52224602d1a75c08bf89f04Jim Miller
942eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        public IntentBuilder(Context context) {
952eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent = new Intent(context, ChooseLockPattern.class);
962eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false);
972eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false);
9840e187b3641ac3084c706b10d2213b91a53da5d1Pavel Grafov            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
992eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        }
1002eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam
1012eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        public IntentBuilder setUserId(int userId) {
1022eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(Intent.EXTRA_USER_ID, userId);
1032eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            return this;
1042eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        }
105a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales
1062eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        public IntentBuilder setChallenge(long challenge) {
1072eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
1082eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
1092eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            return this;
1102eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        }
1112eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam
1122eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        public IntentBuilder setPattern(String pattern) {
1132eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pattern);
1142eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            return this;
1152eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        }
1162eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam
117b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam        public IntentBuilder setForFingerprint(boolean forFingerprint) {
118b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, forFingerprint);
119b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam            return this;
120b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam        }
121b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam
1222eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        public Intent build() {
1232eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            return mIntent;
1242eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        }
1256609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales    }
1266609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales
12717e9e1933055b207473b488595b2887bfcaea32eJim Miller    @Override
128a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani    protected boolean isValidFragment(String fragmentName) {
129a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani        if (ChooseLockPatternFragment.class.getName().equals(fragmentName)) return true;
130a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani        return false;
131a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani    }
132a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani
1336b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam    /* package */ Class<? extends Fragment> getFragmentClass() {
1346b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam        return ChooseLockPatternFragment.class;
1356b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam    }
1366b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam
137a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani    @Override
13871fde52ae36f134e93835bee53bc4bfe5481bba0Udam Saini    protected void onCreate(Bundle savedInstanceState) {
13917e9e1933055b207473b488595b2887bfcaea32eJim Miller        // requestWindowFeature(Window.FEATURE_NO_TITLE);
14017e9e1933055b207473b488595b2887bfcaea32eJim Miller        super.onCreate(savedInstanceState);
141b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam        boolean forFingerprint = getIntent()
142b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam                .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
143b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam        setTitle(forFingerprint ? R.string.lockpassword_choose_your_pattern_header_for_fingerprint
144b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam                : R.string.lockpassword_choose_your_pattern_header);
145d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam        LinearLayout layout = (LinearLayout) findViewById(R.id.content_parent);
146d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam        layout.setFitsSystemWindows(false);
14717e9e1933055b207473b488595b2887bfcaea32eJim Miller    }
148afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
14917e9e1933055b207473b488595b2887bfcaea32eJim Miller    @Override
15017e9e1933055b207473b488595b2887bfcaea32eJim Miller    public boolean onKeyDown(int keyCode, KeyEvent event) {
15117e9e1933055b207473b488595b2887bfcaea32eJim Miller        // *** TODO ***
15217e9e1933055b207473b488595b2887bfcaea32eJim Miller        // chooseLockPatternFragment.onKeyDown(keyCode, event);
15317e9e1933055b207473b488595b2887bfcaea32eJim Miller        return super.onKeyDown(keyCode, event);
15417e9e1933055b207473b488595b2887bfcaea32eJim Miller    }
155afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1562d0b3447360666847c483e6ce2521846c66c25c1Fan Zhang    public static class ChooseLockPatternFragment extends InstrumentedPreferenceFragment
1573e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            implements View.OnClickListener, SaveAndFinishWorker.Listener {
158afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
15917e9e1933055b207473b488595b2887bfcaea32eJim Miller        public static final int CONFIRM_EXISTING_REQUEST = 55;
160afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
16117e9e1933055b207473b488595b2887bfcaea32eJim Miller        // how long after a confirmation message is shown before moving on
16217e9e1933055b207473b488595b2887bfcaea32eJim Miller        static final int INFORMATION_MSG_TIMEOUT_MS = 3000;
163afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
16417e9e1933055b207473b488595b2887bfcaea32eJim Miller        // how long we wait to clear a wrong pattern
16517e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
166afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
16717e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final int ID_EMPTY_MESSAGE = -1;
168afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1693e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
1703e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
171a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales        private String mCurrentPattern;
1726609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales        private boolean mHasChallenge;
1736609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales        private long mChallenge;
17417e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected TextView mHeaderText;
17517e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected LockPatternView mLockPatternView;
17617e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected TextView mFooterText;
17717e9e1933055b207473b488595b2887bfcaea32eJim Miller        private TextView mFooterLeftButton;
17817e9e1933055b207473b488595b2887bfcaea32eJim Miller        private TextView mFooterRightButton;
17917e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected List<LockPatternView.Cell> mChosenPattern = null;
18092779ce70156031f4fa3b8c2d84305f5b3b44105Udam Saini        private boolean mHideDrawer = false;
181afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
182011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei        // ScrollView that contains title and header, only exist in land mode
183011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei        private ScrollView mTitleHeaderScrollView;
184011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei
18517e9e1933055b207473b488595b2887bfcaea32eJim Miller        /**
18617e9e1933055b207473b488595b2887bfcaea32eJim Miller         * The patten used during the help screen to show how to draw a pattern.
18717e9e1933055b207473b488595b2887bfcaea32eJim Miller         */
18817e9e1933055b207473b488595b2887bfcaea32eJim Miller        private final List<LockPatternView.Cell> mAnimatePattern =
18917e9e1933055b207473b488595b2887bfcaea32eJim Miller                Collections.unmodifiableList(Lists.newArrayList(
19017e9e1933055b207473b488595b2887bfcaea32eJim Miller                        LockPatternView.Cell.of(0, 0),
19117e9e1933055b207473b488595b2887bfcaea32eJim Miller                        LockPatternView.Cell.of(0, 1),
19217e9e1933055b207473b488595b2887bfcaea32eJim Miller                        LockPatternView.Cell.of(1, 1),
19317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        LockPatternView.Cell.of(2, 1)
19417e9e1933055b207473b488595b2887bfcaea32eJim Miller                ));
19517e9e1933055b207473b488595b2887bfcaea32eJim Miller
19617e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
19717e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onActivityResult(int requestCode, int resultCode,
19817e9e1933055b207473b488595b2887bfcaea32eJim Miller                Intent data) {
19917e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onActivityResult(requestCode, resultCode, data);
20017e9e1933055b207473b488595b2887bfcaea32eJim Miller            switch (requestCode) {
20117e9e1933055b207473b488595b2887bfcaea32eJim Miller                case CONFIRM_EXISTING_REQUEST:
20217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (resultCode != Activity.RESULT_OK) {
20317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        getActivity().setResult(RESULT_FINISHED);
20417e9e1933055b207473b488595b2887bfcaea32eJim Miller                        getActivity().finish();
205a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                    } else {
206a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                        mCurrentPattern = data.getStringExtra(
207a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                                ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
20817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
209a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales
21017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    updateStage(Stage.Introduction);
21117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
212afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
21317e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
214afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
215af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        protected void setRightButtonEnabled(boolean enabled) {
216af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            mFooterRightButton.setEnabled(enabled);
217af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        }
218af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam
219af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        protected void setRightButtonText(int text) {
220af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            mFooterRightButton.setText(text);
221af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        }
222af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam
22317e9e1933055b207473b488595b2887bfcaea32eJim Miller        /**
22417e9e1933055b207473b488595b2887bfcaea32eJim Miller         * The pattern listener that responds according to a user choosing a new
22517e9e1933055b207473b488595b2887bfcaea32eJim Miller         * lock pattern.
22617e9e1933055b207473b488595b2887bfcaea32eJim Miller         */
22717e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected LockPatternView.OnPatternListener mChooseNewLockPatternListener =
22817e9e1933055b207473b488595b2887bfcaea32eJim Miller                new LockPatternView.OnPatternListener() {
22917e9e1933055b207473b488595b2887bfcaea32eJim Miller
23017e9e1933055b207473b488595b2887bfcaea32eJim Miller                public void onPatternStart() {
23117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.removeCallbacks(mClearPatternRunnable);
23217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    patternInProgress();
233afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
234afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
23517e9e1933055b207473b488595b2887bfcaea32eJim Miller                public void onPatternCleared() {
23617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.removeCallbacks(mClearPatternRunnable);
23717e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
23856544d0e9198ab21dabec621cdf419b52b412dacJim Miller
23917e9e1933055b207473b488595b2887bfcaea32eJim Miller                public void onPatternDetected(List<LockPatternView.Cell> pattern) {
24017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (mUiStage == Stage.NeedToConfirm || mUiStage == Stage.ConfirmWrong) {
24117e9e1933055b207473b488595b2887bfcaea32eJim Miller                        if (mChosenPattern == null) throw new IllegalStateException(
24217e9e1933055b207473b488595b2887bfcaea32eJim Miller                                "null chosen pattern in stage 'need to confirm");
24317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        if (mChosenPattern.equals(pattern)) {
24417e9e1933055b207473b488595b2887bfcaea32eJim Miller                            updateStage(Stage.ChoiceConfirmed);
24517e9e1933055b207473b488595b2887bfcaea32eJim Miller                        } else {
24617e9e1933055b207473b488595b2887bfcaea32eJim Miller                            updateStage(Stage.ConfirmWrong);
24717e9e1933055b207473b488595b2887bfcaea32eJim Miller                        }
24817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else if (mUiStage == Stage.Introduction || mUiStage == Stage.ChoiceTooShort){
24917e9e1933055b207473b488595b2887bfcaea32eJim Miller                        if (pattern.size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
25017e9e1933055b207473b488595b2887bfcaea32eJim Miller                            updateStage(Stage.ChoiceTooShort);
25117e9e1933055b207473b488595b2887bfcaea32eJim Miller                        } else {
25217e9e1933055b207473b488595b2887bfcaea32eJim Miller                            mChosenPattern = new ArrayList<LockPatternView.Cell>(pattern);
25317e9e1933055b207473b488595b2887bfcaea32eJim Miller                            updateStage(Stage.FirstChoiceValid);
25417e9e1933055b207473b488595b2887bfcaea32eJim Miller                        }
25517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else {
25617e9e1933055b207473b488595b2887bfcaea32eJim Miller                        throw new IllegalStateException("Unexpected stage " + mUiStage + " when "
25717e9e1933055b207473b488595b2887bfcaea32eJim Miller                                + "entering the pattern.");
25817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
25917e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
26056544d0e9198ab21dabec621cdf419b52b412dacJim Miller
26117e9e1933055b207473b488595b2887bfcaea32eJim Miller                public void onPatternCellAdded(List<Cell> pattern) {
262afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
26317e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
264afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
26517e9e1933055b207473b488595b2887bfcaea32eJim Miller                private void patternInProgress() {
26617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mHeaderText.setText(R.string.lockpattern_recording_inprogress);
26717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mFooterText.setText("");
26817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mFooterLeftButton.setEnabled(false);
26917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mFooterRightButton.setEnabled(false);
270011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei
271011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                    if (mTitleHeaderScrollView != null) {
272011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                        mTitleHeaderScrollView.post(new Runnable() {
273011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                            @Override
274011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                            public void run() {
275011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                                mTitleHeaderScrollView.fullScroll(ScrollView.FOCUS_DOWN);
276011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                            }
277011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                        });
278011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                    }
27917e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
28017e9e1933055b207473b488595b2887bfcaea32eJim Miller         };
281afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
2828a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren        @Override
2836507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang        public int getMetricsCategory() {
2849d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wren            return MetricsEvent.CHOOSE_LOCK_PATTERN;
2858a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren        }
2868a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren
287afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
288afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /**
28917e9e1933055b207473b488595b2887bfcaea32eJim Miller         * The states of the left footer button.
290afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
29117e9e1933055b207473b488595b2887bfcaea32eJim Miller        enum LeftButtonMode {
29217e9e1933055b207473b488595b2887bfcaea32eJim Miller            Cancel(R.string.cancel, true),
29317e9e1933055b207473b488595b2887bfcaea32eJim Miller            CancelDisabled(R.string.cancel, false),
29417e9e1933055b207473b488595b2887bfcaea32eJim Miller            Retry(R.string.lockpattern_retry_button_text, true),
29517e9e1933055b207473b488595b2887bfcaea32eJim Miller            RetryDisabled(R.string.lockpattern_retry_button_text, false),
29617e9e1933055b207473b488595b2887bfcaea32eJim Miller            Gone(ID_EMPTY_MESSAGE, false);
29717e9e1933055b207473b488595b2887bfcaea32eJim Miller
29817e9e1933055b207473b488595b2887bfcaea32eJim Miller
29917e9e1933055b207473b488595b2887bfcaea32eJim Miller            /**
30017e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param text The displayed text for this mode.
30117e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param enabled Whether the button should be enabled.
30217e9e1933055b207473b488595b2887bfcaea32eJim Miller             */
30317e9e1933055b207473b488595b2887bfcaea32eJim Miller            LeftButtonMode(int text, boolean enabled) {
30417e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.text = text;
30517e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.enabled = enabled;
30617e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
307afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
30817e9e1933055b207473b488595b2887bfcaea32eJim Miller            final int text;
30917e9e1933055b207473b488595b2887bfcaea32eJim Miller            final boolean enabled;
31017e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
311afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
312afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /**
31317e9e1933055b207473b488595b2887bfcaea32eJim Miller         * The states of the right button.
314afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
31517e9e1933055b207473b488595b2887bfcaea32eJim Miller        enum RightButtonMode {
316c57b19d80c100bb4a19bb2d4b8589bc12cbfd66eMaurice Lam            Continue(R.string.next_label, true),
317c57b19d80c100bb4a19bb2d4b8589bc12cbfd66eMaurice Lam            ContinueDisabled(R.string.next_label, false),
31817e9e1933055b207473b488595b2887bfcaea32eJim Miller            Confirm(R.string.lockpattern_confirm_button_text, true),
31917e9e1933055b207473b488595b2887bfcaea32eJim Miller            ConfirmDisabled(R.string.lockpattern_confirm_button_text, false),
32017e9e1933055b207473b488595b2887bfcaea32eJim Miller            Ok(android.R.string.ok, true);
32117e9e1933055b207473b488595b2887bfcaea32eJim Miller
32217e9e1933055b207473b488595b2887bfcaea32eJim Miller            /**
32317e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param text The displayed text for this mode.
32417e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param enabled Whether the button should be enabled.
32517e9e1933055b207473b488595b2887bfcaea32eJim Miller             */
32617e9e1933055b207473b488595b2887bfcaea32eJim Miller            RightButtonMode(int text, boolean enabled) {
32717e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.text = text;
32817e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.enabled = enabled;
32917e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
330afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
33117e9e1933055b207473b488595b2887bfcaea32eJim Miller            final int text;
33217e9e1933055b207473b488595b2887bfcaea32eJim Miller            final boolean enabled;
33317e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
334afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
335afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /**
33617e9e1933055b207473b488595b2887bfcaea32eJim Miller         * Keep track internally of where the user is in choosing a pattern.
337afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
33817e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected enum Stage {
33917e9e1933055b207473b488595b2887bfcaea32eJim Miller
34017e9e1933055b207473b488595b2887bfcaea32eJim Miller            Introduction(
34117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_recording_intro_header,
34217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Cancel, RightButtonMode.ContinueDisabled,
34363cf89a49a751c49bf60b9898e7d59f02b91c046Jim Miller                    ID_EMPTY_MESSAGE, true),
34417e9e1933055b207473b488595b2887bfcaea32eJim Miller            HelpScreen(
34517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_settings_help_how_to_record,
34617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Gone, RightButtonMode.Ok, ID_EMPTY_MESSAGE, false),
34717e9e1933055b207473b488595b2887bfcaea32eJim Miller            ChoiceTooShort(
34817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_recording_incorrect_too_short,
34917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Retry, RightButtonMode.ContinueDisabled,
35017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    ID_EMPTY_MESSAGE, true),
35117e9e1933055b207473b488595b2887bfcaea32eJim Miller            FirstChoiceValid(
35217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_pattern_entered_header,
35317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Retry, RightButtonMode.Continue, ID_EMPTY_MESSAGE, false),
35417e9e1933055b207473b488595b2887bfcaea32eJim Miller            NeedToConfirm(
35517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_need_to_confirm,
35677cb854d689cd5c49e14f80abb7803d77ced2e79Jim Miller                    LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
35717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    ID_EMPTY_MESSAGE, true),
35817e9e1933055b207473b488595b2887bfcaea32eJim Miller            ConfirmWrong(
35917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_need_to_unlock_wrong,
36017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
36117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    ID_EMPTY_MESSAGE, true),
36217e9e1933055b207473b488595b2887bfcaea32eJim Miller            ChoiceConfirmed(
36317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_pattern_confirmed_header,
36417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Cancel, RightButtonMode.Confirm, ID_EMPTY_MESSAGE, false);
36517e9e1933055b207473b488595b2887bfcaea32eJim Miller
36617e9e1933055b207473b488595b2887bfcaea32eJim Miller
36717e9e1933055b207473b488595b2887bfcaea32eJim Miller            /**
36817e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param headerMessage The message displayed at the top.
36917e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param leftMode The mode of the left button.
37017e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param rightMode The mode of the right button.
37117e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param footerMessage The footer message.
37217e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param patternEnabled Whether the pattern widget is enabled.
37317e9e1933055b207473b488595b2887bfcaea32eJim Miller             */
37417e9e1933055b207473b488595b2887bfcaea32eJim Miller            Stage(int headerMessage,
37517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode leftMode,
37617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    RightButtonMode rightMode,
37717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    int footerMessage, boolean patternEnabled) {
37817e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.headerMessage = headerMessage;
37917e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.leftMode = leftMode;
38017e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.rightMode = rightMode;
38117e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.footerMessage = footerMessage;
38217e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.patternEnabled = patternEnabled;
38317e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
38417e9e1933055b207473b488595b2887bfcaea32eJim Miller
38517e9e1933055b207473b488595b2887bfcaea32eJim Miller            final int headerMessage;
38617e9e1933055b207473b488595b2887bfcaea32eJim Miller            final LeftButtonMode leftMode;
38717e9e1933055b207473b488595b2887bfcaea32eJim Miller            final RightButtonMode rightMode;
38817e9e1933055b207473b488595b2887bfcaea32eJim Miller            final int footerMessage;
38917e9e1933055b207473b488595b2887bfcaea32eJim Miller            final boolean patternEnabled;
390afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
391afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
39217e9e1933055b207473b488595b2887bfcaea32eJim Miller        private Stage mUiStage = Stage.Introduction;
393afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
39417e9e1933055b207473b488595b2887bfcaea32eJim Miller        private Runnable mClearPatternRunnable = new Runnable() {
39517e9e1933055b207473b488595b2887bfcaea32eJim Miller            public void run() {
39617e9e1933055b207473b488595b2887bfcaea32eJim Miller                mLockPatternView.clearPattern();
39717e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
39817e9e1933055b207473b488595b2887bfcaea32eJim Miller        };
399afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
40017e9e1933055b207473b488595b2887bfcaea32eJim Miller        private ChooseLockSettingsHelper mChooseLockSettingsHelper;
4013e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private SaveAndFinishWorker mSaveAndFinishWorker;
402fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri        private int mUserId;
4037af28ecb66b6507803244bd7584b45415044ac70Ajay Nadathur        private boolean mForFingerprint;
404afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
40517e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String KEY_UI_STAGE = "uiStage";
40617e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String KEY_PATTERN_CHOICE = "chosenPattern";
407a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales        private static final String KEY_CURRENT_PATTERN = "currentPattern";
40800d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
40917e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
41017e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onCreate(Bundle savedInstanceState) {
41117e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onCreate(savedInstanceState);
41217e9e1933055b207473b488595b2887bfcaea32eJim Miller            mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
41366026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani            if (!(getActivity() instanceof ChooseLockPattern)) {
41466026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani                throw new SecurityException("Fragment contained in wrong activity");
41566026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani            }
416fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri            Intent intent = getActivity().getIntent();
417fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri            // Only take this argument into account if it belongs to the current profile.
418194300dff340d67255d12762ffb376b7ba201c87Benjamin Franz            mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras());
41962775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos
42062775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos            if (intent.getBooleanExtra(
42162775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                    ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) {
42262775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                SaveAndFinishWorker w = new SaveAndFinishWorker();
42362775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                final boolean required = getActivity().getIntent().getBooleanExtra(
42462775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                        EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
42562775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                String current = intent.getStringExtra(
42662775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                        ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
42762775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                w.setBlocking(true);
42862775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                w.setListener(this);
42962775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                w.start(mChooseLockSettingsHelper.utils(), required,
43062775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                        false, 0, LockPatternUtils.stringToPattern(current), current, mUserId);
43162775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos            }
43292779ce70156031f4fa3b8c2d84305f5b3b44105Udam Saini            mHideDrawer = getActivity().getIntent().getBooleanExtra(EXTRA_HIDE_DRAWER, false);
4337af28ecb66b6507803244bd7584b45415044ac70Ajay Nadathur            mForFingerprint = intent.getBooleanExtra(
4347af28ecb66b6507803244bd7584b45415044ac70Ajay Nadathur                    ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
43517e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
436afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
43717e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
43817e9e1933055b207473b488595b2887bfcaea32eJim Miller        public View onCreateView(LayoutInflater inflater, ViewGroup container,
43917e9e1933055b207473b488595b2887bfcaea32eJim Miller                Bundle savedInstanceState) {
440d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam            final GlifLayout layout = (GlifLayout) inflater.inflate(
441d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam                    R.layout.choose_lock_pattern, container, false);
442d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam            layout.setHeaderText(getActivity().getTitle());
4437af28ecb66b6507803244bd7584b45415044ac70Ajay Nadathur            if (mForFingerprint) {
4447af28ecb66b6507803244bd7584b45415044ac70Ajay Nadathur                layout.setIcon(getActivity().getDrawable(R.drawable.ic_fingerprint_header));
4457af28ecb66b6507803244bd7584b45415044ac70Ajay Nadathur            }
446d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam            return layout;
4476b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam        }
44817e9e1933055b207473b488595b2887bfcaea32eJim Miller
4496b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam        @Override
4506b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam        public void onViewCreated(View view, Bundle savedInstanceState) {
4516b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam            super.onViewCreated(view, savedInstanceState);
45217e9e1933055b207473b488595b2887bfcaea32eJim Miller            mHeaderText = (TextView) view.findViewById(R.id.headerText);
45317e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern);
45417e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
45517e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.setTactileFeedbackEnabled(
45617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mChooseLockSettingsHelper.utils().isTactileFeedbackEnabled());
45717e9e1933055b207473b488595b2887bfcaea32eJim Miller
45817e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterText = (TextView) view.findViewById(R.id.footerText);
45917e9e1933055b207473b488595b2887bfcaea32eJim Miller
46017e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterLeftButton = (TextView) view.findViewById(R.id.footerLeftButton);
46117e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterRightButton = (TextView) view.findViewById(R.id.footerRightButton);
46217e9e1933055b207473b488595b2887bfcaea32eJim Miller
463011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei            mTitleHeaderScrollView = (ScrollView) view.findViewById(R.id
464011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                    .scroll_layout_title_header);
465011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei
46617e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterLeftButton.setOnClickListener(this);
46717e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterRightButton.setOnClickListener(this);
46817e9e1933055b207473b488595b2887bfcaea32eJim Miller
46917e9e1933055b207473b488595b2887bfcaea32eJim Miller            // make it so unhandled touch events within the unlock screen go to the
47017e9e1933055b207473b488595b2887bfcaea32eJim Miller            // lock pattern view.
47117e9e1933055b207473b488595b2887bfcaea32eJim Miller            final LinearLayoutWithDefaultTouchRecepient topLayout
47217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    = (LinearLayoutWithDefaultTouchRecepient) view.findViewById(
47317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.id.topLayout);
47417e9e1933055b207473b488595b2887bfcaea32eJim Miller            topLayout.setDefaultTouchRecepient(mLockPatternView);
47517e9e1933055b207473b488595b2887bfcaea32eJim Miller
47617e9e1933055b207473b488595b2887bfcaea32eJim Miller            final boolean confirmCredentials = getActivity().getIntent()
4772eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam                    .getBooleanExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, true);
4786609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales            Intent intent = getActivity().getIntent();
4796609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales            mCurrentPattern = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
4806609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales            mHasChallenge = intent.getBooleanExtra(
4816609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales                    ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
4826609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales            mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
48317e9e1933055b207473b488595b2887bfcaea32eJim Miller
48417e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (savedInstanceState == null) {
48517e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (confirmCredentials) {
48617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    // first launch. As a security measure, we're in NeedToConfirm mode until we
48717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    // know there isn't an existing password or the user confirms their password.
48817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    updateStage(Stage.NeedToConfirm);
48917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    boolean launchedConfirmationActivity =
49017e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mChooseLockSettingsHelper.launchConfirmationActivity(
4918a09b619aeb233e2aab1919301f162d8acf1f0f0Jorim Jaggi                                CONFIRM_EXISTING_REQUEST,
492fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri                                getString(R.string.unlock_set_unlock_launch_picker_title), true,
493fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri                                mUserId);
49417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (!launchedConfirmationActivity) {
49517e9e1933055b207473b488595b2887bfcaea32eJim Miller                        updateStage(Stage.Introduction);
49617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
49717e9e1933055b207473b488595b2887bfcaea32eJim Miller                } else {
498bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                    updateStage(Stage.Introduction);
499bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                }
500bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller            } else {
50117e9e1933055b207473b488595b2887bfcaea32eJim Miller                // restore from previous state
50217e9e1933055b207473b488595b2887bfcaea32eJim Miller                final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE);
50317e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (patternString != null) {
50417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mChosenPattern = LockPatternUtils.stringToPattern(patternString);
50517e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
506a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales
507a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                if (mCurrentPattern == null) {
508a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                    mCurrentPattern = savedInstanceState.getString(KEY_CURRENT_PATTERN);
509a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                }
51017e9e1933055b207473b488595b2887bfcaea32eJim Miller                updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
5113e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
5123e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                // Re-attach to the exiting worker if there is one.
5133e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                mSaveAndFinishWorker = (SaveAndFinishWorker) getFragmentManager().findFragmentByTag(
5143e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                        FRAGMENT_TAG_SAVE_AND_FINISH);
515afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
516afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
517afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
518bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        @Override
519bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        public void onResume() {
520bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia            super.onResume();
521e47a2ab83eac80ed6e46606668db21b178168da7Xiyuan Xia            updateStage(mUiStage);
522e47a2ab83eac80ed6e46606668db21b178168da7Xiyuan Xia
5233e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (mSaveAndFinishWorker != null) {
5243e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                setRightButtonEnabled(false);
5253e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                mSaveAndFinishWorker.setListener(this);
5263e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            }
527bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        }
528bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia
529bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        @Override
530bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        public void onPause() {
531bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia            super.onPause();
5323e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (mSaveAndFinishWorker != null) {
5333e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                mSaveAndFinishWorker.setListener(null);
534bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia            }
535bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        }
536bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia
537ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam        protected Intent getRedactionInterstitialIntent(Context context) {
538f6077f4757183ae8b31af0928c895c806241b593Clara Bayarri            return RedactionInterstitial.createStartIntent(context, mUserId);
539ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam        }
540ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam
541af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        public void handleLeftButton() {
542af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            if (mUiStage.leftMode == LeftButtonMode.Retry) {
543af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                mChosenPattern = null;
544af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                mLockPatternView.clearPattern();
545af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                updateStage(Stage.Introduction);
546af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            } else if (mUiStage.leftMode == LeftButtonMode.Cancel) {
547af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                getActivity().finish();
548af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            } else {
549af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                throw new IllegalStateException("left footer button pressed, but stage of " +
55017e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mUiStage + " doesn't make sense");
551af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            }
552af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        }
55317e9e1933055b207473b488595b2887bfcaea32eJim Miller
554af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        public void handleRightButton() {
555af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            if (mUiStage.rightMode == RightButtonMode.Continue) {
556af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                if (mUiStage != Stage.FirstChoiceValid) {
557af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                    throw new IllegalStateException("expected ui stage "
558af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                            + Stage.FirstChoiceValid + " when button is "
559af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                            + RightButtonMode.Continue);
560af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                }
561af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                updateStage(Stage.NeedToConfirm);
562af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            } else if (mUiStage.rightMode == RightButtonMode.Confirm) {
563af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                if (mUiStage != Stage.ChoiceConfirmed) {
564af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                    throw new IllegalStateException("expected ui stage " + Stage.ChoiceConfirmed
565af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                            + " when button is " + RightButtonMode.Confirm);
566af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                }
5673e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                startSaveAndFinish();
568af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            } else if (mUiStage.rightMode == RightButtonMode.Ok) {
569af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                if (mUiStage != Stage.HelpScreen) {
570af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                    throw new IllegalStateException("Help screen is only mode with ok button, "
571af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                            + "but stage is " + mUiStage);
572afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
573af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                mLockPatternView.clearPattern();
574af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                mLockPatternView.setDisplayMode(DisplayMode.Correct);
575af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                updateStage(Stage.Introduction);
576af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            }
577af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        }
578af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam
579af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        public void onClick(View v) {
580af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            if (v == mFooterLeftButton) {
581af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                handleLeftButton();
582af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            } else if (v == mFooterRightButton) {
583af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                handleRightButton();
584afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
585afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
586afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
58717e9e1933055b207473b488595b2887bfcaea32eJim Miller        public boolean onKeyDown(int keyCode, KeyEvent event) {
58817e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
58917e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (mUiStage == Stage.HelpScreen) {
59017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    updateStage(Stage.Introduction);
59117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    return true;
59217e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
59317e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
59417e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (keyCode == KeyEvent.KEYCODE_MENU && mUiStage == Stage.Introduction) {
59517e9e1933055b207473b488595b2887bfcaea32eJim Miller                updateStage(Stage.HelpScreen);
596afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return true;
597afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
59817e9e1933055b207473b488595b2887bfcaea32eJim Miller            return false;
599afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
600afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
60117e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onSaveInstanceState(Bundle outState) {
60217e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onSaveInstanceState(outState);
603afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
60417e9e1933055b207473b488595b2887bfcaea32eJim Miller            outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
60517e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (mChosenPattern != null) {
60617e9e1933055b207473b488595b2887bfcaea32eJim Miller                outState.putString(KEY_PATTERN_CHOICE,
60717e9e1933055b207473b488595b2887bfcaea32eJim Miller                        LockPatternUtils.patternToString(mChosenPattern));
60817e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
609a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales
610a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales            if (mCurrentPattern != null) {
611a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                outState.putString(KEY_CURRENT_PATTERN,
612a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                        mCurrentPattern);
613a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales            }
614afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
615afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
61617e9e1933055b207473b488595b2887bfcaea32eJim Miller        /**
61717e9e1933055b207473b488595b2887bfcaea32eJim Miller         * Updates the messages and buttons appropriate to what stage the user
61817e9e1933055b207473b488595b2887bfcaea32eJim Miller         * is at in choosing a view.  This doesn't handle clearing out the pattern;
61917e9e1933055b207473b488595b2887bfcaea32eJim Miller         * the pattern is expected to be in the right state.
62017e9e1933055b207473b488595b2887bfcaea32eJim Miller         * @param stage
62117e9e1933055b207473b488595b2887bfcaea32eJim Miller         */
62217e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected void updateStage(Stage stage) {
623eef72c39ae83697b1beaa148ec56aced67382fecalanv            final Stage previousStage = mUiStage;
624afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
62517e9e1933055b207473b488595b2887bfcaea32eJim Miller            mUiStage = stage;
626afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
62717e9e1933055b207473b488595b2887bfcaea32eJim Miller            // header text, footer text, visibility and
62817e9e1933055b207473b488595b2887bfcaea32eJim Miller            // enabled state all known from the stage
62917e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (stage == Stage.ChoiceTooShort) {
63017e9e1933055b207473b488595b2887bfcaea32eJim Miller                mHeaderText.setText(
63117e9e1933055b207473b488595b2887bfcaea32eJim Miller                        getResources().getString(
63217e9e1933055b207473b488595b2887bfcaea32eJim Miller                                stage.headerMessage,
63317e9e1933055b207473b488595b2887bfcaea32eJim Miller                                LockPatternUtils.MIN_LOCK_PATTERN_SIZE));
63417e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
63517e9e1933055b207473b488595b2887bfcaea32eJim Miller                mHeaderText.setText(stage.headerMessage);
63617e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
63717e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (stage.footerMessage == ID_EMPTY_MESSAGE) {
63817e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterText.setText("");
63917e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
64017e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterText.setText(stage.footerMessage);
64117e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
642afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
64317e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (stage.leftMode == LeftButtonMode.Gone) {
64417e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterLeftButton.setVisibility(View.GONE);
64517e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
64617e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterLeftButton.setVisibility(View.VISIBLE);
64717e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterLeftButton.setText(stage.leftMode.text);
64817e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterLeftButton.setEnabled(stage.leftMode.enabled);
64917e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
650afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
651af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            setRightButtonText(stage.rightMode.text);
652af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            setRightButtonEnabled(stage.rightMode.enabled);
653afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
6543e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            // same for whether the pattern is enabled
65517e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (stage.patternEnabled) {
65617e9e1933055b207473b488595b2887bfcaea32eJim Miller                mLockPatternView.enableInput();
65717e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
65817e9e1933055b207473b488595b2887bfcaea32eJim Miller                mLockPatternView.disableInput();
65917e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
660afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
66117e9e1933055b207473b488595b2887bfcaea32eJim Miller            // the rest of the stuff varies enough that it is easier just to handle
66217e9e1933055b207473b488595b2887bfcaea32eJim Miller            // on a case by case basis.
66317e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.setDisplayMode(DisplayMode.Correct);
66400da4f6d3b7cd2aa347b88e3f15b3b6ddd3e5803Selim Cinek            boolean announceAlways = false;
66517e9e1933055b207473b488595b2887bfcaea32eJim Miller
66617e9e1933055b207473b488595b2887bfcaea32eJim Miller            switch (mUiStage) {
66717e9e1933055b207473b488595b2887bfcaea32eJim Miller                case Introduction:
66817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.clearPattern();
66917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
67017e9e1933055b207473b488595b2887bfcaea32eJim Miller                case HelpScreen:
67117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.setPattern(DisplayMode.Animate, mAnimatePattern);
67217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
67317e9e1933055b207473b488595b2887bfcaea32eJim Miller                case ChoiceTooShort:
67417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.setDisplayMode(DisplayMode.Wrong);
67517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    postClearPatternRunnable();
67600da4f6d3b7cd2aa347b88e3f15b3b6ddd3e5803Selim Cinek                    announceAlways = true;
67717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
67817e9e1933055b207473b488595b2887bfcaea32eJim Miller                case FirstChoiceValid:
67917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
68017e9e1933055b207473b488595b2887bfcaea32eJim Miller                case NeedToConfirm:
68117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.clearPattern();
68217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
68317e9e1933055b207473b488595b2887bfcaea32eJim Miller                case ConfirmWrong:
68417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.setDisplayMode(DisplayMode.Wrong);
68517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    postClearPatternRunnable();
68600da4f6d3b7cd2aa347b88e3f15b3b6ddd3e5803Selim Cinek                    announceAlways = true;
68717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
68817e9e1933055b207473b488595b2887bfcaea32eJim Miller                case ChoiceConfirmed:
68917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
69017e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
691eef72c39ae83697b1beaa148ec56aced67382fecalanv
692eef72c39ae83697b1beaa148ec56aced67382fecalanv            // If the stage changed, announce the header for accessibility. This
693eef72c39ae83697b1beaa148ec56aced67382fecalanv            // is a no-op when accessibility is disabled.
69400da4f6d3b7cd2aa347b88e3f15b3b6ddd3e5803Selim Cinek            if (previousStage != stage || announceAlways) {
695eef72c39ae83697b1beaa148ec56aced67382fecalanv                mHeaderText.announceForAccessibility(mHeaderText.getText());
696eef72c39ae83697b1beaa148ec56aced67382fecalanv            }
697afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
698afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
69917e9e1933055b207473b488595b2887bfcaea32eJim Miller        // clear the wrong pattern unless they have started a new one
70017e9e1933055b207473b488595b2887bfcaea32eJim Miller        // already
70117e9e1933055b207473b488595b2887bfcaea32eJim Miller        private void postClearPatternRunnable() {
70217e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.removeCallbacks(mClearPatternRunnable);
70317e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
70417e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
705afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
7063e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private void startSaveAndFinish() {
7073e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (mSaveAndFinishWorker != null) {
7083e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                Log.w(TAG, "startSaveAndFinish with an existing SaveAndFinishWorker.");
7093e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                return;
7103e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            }
711e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
7123e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            setRightButtonEnabled(false);
71390d6c568cf24178669254964af343f729639b31dAdrian Roos
7143e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            mSaveAndFinishWorker = new SaveAndFinishWorker();
7155bb1e4fb909a5f0e0574d3572ea1edcf32a2190fRobin Lee            mSaveAndFinishWorker.setListener(this);
7165bb1e4fb909a5f0e0574d3572ea1edcf32a2190fRobin Lee
7173e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            getFragmentManager().beginTransaction().add(mSaveAndFinishWorker,
7183e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                    FRAGMENT_TAG_SAVE_AND_FINISH).commit();
7195bb1e4fb909a5f0e0574d3572ea1edcf32a2190fRobin Lee            getFragmentManager().executePendingTransactions();
720cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence
7213e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            final boolean required = getActivity().getIntent().getBooleanExtra(
7220698a216311acd9ab52224602d1a75c08bf89f04Jim Miller                    EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
7233e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            mSaveAndFinishWorker.start(mChooseLockSettingsHelper.utils(), required,
724fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri                    mHasChallenge, mChallenge, mChosenPattern, mCurrentPattern, mUserId);
7253e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        }
726a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales
7273e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        @Override
7283e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
7293e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            getActivity().setResult(RESULT_FINISHED, resultData);
730e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
7313e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (!wasSecureBefore) {
7323e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                Intent intent = getRedactionInterstitialIntent(getActivity());
7333e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                if (intent != null) {
73492779ce70156031f4fa3b8c2d84305f5b3b44105Udam Saini                    intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
7353e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                    startActivity(intent);
7363e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                }
73717e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
738686ae494f485a5025dfa456b4f32427b3715c337Udam Saini            getActivity().finish();
7393e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        }
7403e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia    }
74100d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
74277c4345373bdf6d6543bc06a04abc026ce762dbeClara Bayarri    public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
7433e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7443e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private List<LockPatternView.Cell> mChosenPattern;
7453e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private String mCurrentPattern;
7463e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private boolean mLockVirgin;
7473e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7483e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        public void start(LockPatternUtils utils, boolean credentialRequired,
7493e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                boolean hasChallenge, long challenge,
750fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri                List<LockPatternView.Cell> chosenPattern, String currentPattern, int userId) {
751b8a22e42d42e6de8fce1a2026c112c12fd0f0f7aClara Bayarri            prepare(utils, credentialRequired, hasChallenge, challenge, userId);
7523e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7533e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            mCurrentPattern = currentPattern;
7543e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            mChosenPattern = chosenPattern;
755fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri            mUserId = userId;
7563e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
757fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri            mLockVirgin = !mUtils.isPatternEverChosen(mUserId);
7583e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7593e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            start();
7603e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        }
7613e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7623e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        @Override
7633e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        protected Intent saveAndVerifyInBackground() {
7643e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            Intent result = null;
765fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri            final int userId = mUserId;
7663e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            mUtils.saveLockPattern(mChosenPattern, mCurrentPattern, userId);
7673e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7683e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (mHasChallenge) {
7693e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                byte[] token;
7703e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                try {
7713e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                    token = mUtils.verifyPattern(mChosenPattern, mChallenge, userId);
7723e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                } catch (RequestThrottledException e) {
7733e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                    token = null;
774cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence                }
775cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence
7763e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                if (token == null) {
7773e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                    Log.e(TAG, "critical: no token returned for known good pattern");
77858c5fb38c75cf04309f74927b3c91c54a645b690Jorim Jaggi                }
779bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia
7803e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                result = new Intent();
7813e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
782bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia            }
783bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia
7843e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            return result;
785bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        }
786bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia
7873e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        @Override
7883e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        protected void finish(Intent resultData) {
7893e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (mLockVirgin) {
790fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri                mUtils.setVisiblePatternEnabled(true, mUserId);
7913e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            }
7923e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7933e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            super.finish(resultData);
79417e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
795afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
796afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
797