ChooseLockPattern.java revision c57b19d80c100bb4a19bb2d4b8589bc12cbfd66e
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;
23afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Bundle;
2491e6c499ca8f33cc093fed4277d2b48ab780b309Andres Moralesimport android.util.Log;
25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.KeyEvent;
2617e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.view.LayoutInflater;
27afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.View;
2817e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.view.ViewGroup;
29d189ac52a4e49291b729d817fc903116abc086d0Maurice Lamimport android.widget.LinearLayout;
30011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyuleiimport android.widget.ScrollView;
31afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.TextView;
32afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
33265d3c2a0c36251bf8a9f571d7239b6dd404d942Tamas Berghammerimport com.android.internal.logging.nano.MetricsProto.MetricsEvent;
3439b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
3539b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternUtils;
3639b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternUtils.RequestThrottledException;
3739b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternView;
3839b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternView.Cell;
3939b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.widget.LockPatternView.DisplayMode;
402eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.EncryptionInterstitial;
412eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.R;
422eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.SettingsActivity;
432eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lamimport com.android.settings.Utils;
442d0b3447360666847c483e6ce2521846c66c25c1Fan Zhangimport com.android.settings.core.InstrumentedPreferenceFragment;
4539b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.settings.notification.RedactionInterstitial;
46d189ac52a4e49291b729d817fc903116abc086d0Maurice Lamimport com.android.setupwizardlib.GlifLayout;
472eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam
4839b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.google.android.collect.Lists;
4939b467482d1bf256a111c757e9b7621c6f523271Jason Monk
50afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.ArrayList;
51afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.Collections;
52afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.List;
53afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
54afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/**
55afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * If the user has a lock pattern set already, makes them confirm the existing one.
56afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Then, prompts the user to choose a lock pattern:
58afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * - prompts for initial pattern
59afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * - asks for confirmation / restart
60afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * - saves chosen password when confirmed
61afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
62263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Megliopublic class ChooseLockPattern extends SettingsActivity {
63afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
64afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Used by the choose lock pattern wizard to indicate the wizard is
65afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * finished, and each activity in the wizard should finish.
66afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * <p>
67afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Previously, each activity in the wizard would finish itself after
68afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * starting the next activity. However, this leads to broken 'Back'
69afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * behavior. So, now an activity does not finish itself until it gets this
70afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * result.
71afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
72afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    static final int RESULT_FINISHED = RESULT_FIRST_USER;
7300d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
7491e6c499ca8f33cc093fed4277d2b48ab780b309Andres Morales    private static final String TAG = "ChooseLockPattern";
7591e6c499ca8f33cc093fed4277d2b48ab780b309Andres Morales
7617e9e1933055b207473b488595b2887bfcaea32eJim Miller    @Override
7717e9e1933055b207473b488595b2887bfcaea32eJim Miller    public Intent getIntent() {
7817e9e1933055b207473b488595b2887bfcaea32eJim Miller        Intent modIntent = new Intent(super.getIntent());
796b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
8017e9e1933055b207473b488595b2887bfcaea32eJim Miller        return modIntent;
8117e9e1933055b207473b488595b2887bfcaea32eJim Miller    }
8200d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
832eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam    public static class IntentBuilder {
842eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        private final Intent mIntent;
850698a216311acd9ab52224602d1a75c08bf89f04Jim Miller
862eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        public IntentBuilder(Context context) {
872eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent = new Intent(context, ChooseLockPattern.class);
882eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false);
892eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false);
902eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        }
912eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam
922eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        public IntentBuilder setUserId(int userId) {
932eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(Intent.EXTRA_USER_ID, userId);
942eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            return this;
952eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        }
96a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales
972eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        public IntentBuilder setChallenge(long challenge) {
982eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
992eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
1002eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            return this;
1012eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        }
1022eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam
1032eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        public IntentBuilder setPattern(String pattern) {
1042eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
1052eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pattern);
1062eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            return this;
1072eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        }
1082eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam
109b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam        public IntentBuilder setForFingerprint(boolean forFingerprint) {
110b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, forFingerprint);
111b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam            return this;
112b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam        }
113b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam
1142eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        public Intent build() {
1152eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam            return mIntent;
1162eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam        }
1176609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales    }
1186609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales
11917e9e1933055b207473b488595b2887bfcaea32eJim Miller    @Override
120a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani    protected boolean isValidFragment(String fragmentName) {
121a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani        if (ChooseLockPatternFragment.class.getName().equals(fragmentName)) return true;
122a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani        return false;
123a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani    }
124a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani
1256b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam    /* package */ Class<? extends Fragment> getFragmentClass() {
1266b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam        return ChooseLockPatternFragment.class;
1276b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam    }
1286b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam
129a677ee210c67d13d15ba0663887675bda16354d8Amith Yamasani    @Override
13071fde52ae36f134e93835bee53bc4bfe5481bba0Udam Saini    protected void onCreate(Bundle savedInstanceState) {
13117e9e1933055b207473b488595b2887bfcaea32eJim Miller        // requestWindowFeature(Window.FEATURE_NO_TITLE);
13217e9e1933055b207473b488595b2887bfcaea32eJim Miller        super.onCreate(savedInstanceState);
133b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam        boolean forFingerprint = getIntent()
134b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam                .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
135b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam        setTitle(forFingerprint ? R.string.lockpassword_choose_your_pattern_header_for_fingerprint
136b49526ee282f13a83ee38358473fcb628b5727a5Maurice Lam                : R.string.lockpassword_choose_your_pattern_header);
137d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam        LinearLayout layout = (LinearLayout) findViewById(R.id.content_parent);
138d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam        layout.setFitsSystemWindows(false);
13917e9e1933055b207473b488595b2887bfcaea32eJim Miller    }
140afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
14117e9e1933055b207473b488595b2887bfcaea32eJim Miller    @Override
14217e9e1933055b207473b488595b2887bfcaea32eJim Miller    public boolean onKeyDown(int keyCode, KeyEvent event) {
14317e9e1933055b207473b488595b2887bfcaea32eJim Miller        // *** TODO ***
14417e9e1933055b207473b488595b2887bfcaea32eJim Miller        // chooseLockPatternFragment.onKeyDown(keyCode, event);
14517e9e1933055b207473b488595b2887bfcaea32eJim Miller        return super.onKeyDown(keyCode, event);
14617e9e1933055b207473b488595b2887bfcaea32eJim Miller    }
147afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1482d0b3447360666847c483e6ce2521846c66c25c1Fan Zhang    public static class ChooseLockPatternFragment extends InstrumentedPreferenceFragment
1493e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            implements View.OnClickListener, SaveAndFinishWorker.Listener {
150afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
15117e9e1933055b207473b488595b2887bfcaea32eJim Miller        public static final int CONFIRM_EXISTING_REQUEST = 55;
152afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
15317e9e1933055b207473b488595b2887bfcaea32eJim Miller        // how long after a confirmation message is shown before moving on
15417e9e1933055b207473b488595b2887bfcaea32eJim Miller        static final int INFORMATION_MSG_TIMEOUT_MS = 3000;
155afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
15617e9e1933055b207473b488595b2887bfcaea32eJim Miller        // how long we wait to clear a wrong pattern
15717e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
158afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
15917e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final int ID_EMPTY_MESSAGE = -1;
160afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
1613e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
1623e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
163a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales        private String mCurrentPattern;
1646609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales        private boolean mHasChallenge;
1656609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales        private long mChallenge;
16617e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected TextView mHeaderText;
16717e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected LockPatternView mLockPatternView;
16817e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected TextView mFooterText;
16917e9e1933055b207473b488595b2887bfcaea32eJim Miller        private TextView mFooterLeftButton;
17017e9e1933055b207473b488595b2887bfcaea32eJim Miller        private TextView mFooterRightButton;
17117e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected List<LockPatternView.Cell> mChosenPattern = null;
17292779ce70156031f4fa3b8c2d84305f5b3b44105Udam Saini        private boolean mHideDrawer = false;
173afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
174011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei        // ScrollView that contains title and header, only exist in land mode
175011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei        private ScrollView mTitleHeaderScrollView;
176011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei
17717e9e1933055b207473b488595b2887bfcaea32eJim Miller        /**
17817e9e1933055b207473b488595b2887bfcaea32eJim Miller         * The patten used during the help screen to show how to draw a pattern.
17917e9e1933055b207473b488595b2887bfcaea32eJim Miller         */
18017e9e1933055b207473b488595b2887bfcaea32eJim Miller        private final List<LockPatternView.Cell> mAnimatePattern =
18117e9e1933055b207473b488595b2887bfcaea32eJim Miller                Collections.unmodifiableList(Lists.newArrayList(
18217e9e1933055b207473b488595b2887bfcaea32eJim Miller                        LockPatternView.Cell.of(0, 0),
18317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        LockPatternView.Cell.of(0, 1),
18417e9e1933055b207473b488595b2887bfcaea32eJim Miller                        LockPatternView.Cell.of(1, 1),
18517e9e1933055b207473b488595b2887bfcaea32eJim Miller                        LockPatternView.Cell.of(2, 1)
18617e9e1933055b207473b488595b2887bfcaea32eJim Miller                ));
18717e9e1933055b207473b488595b2887bfcaea32eJim Miller
18817e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
18917e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onActivityResult(int requestCode, int resultCode,
19017e9e1933055b207473b488595b2887bfcaea32eJim Miller                Intent data) {
19117e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onActivityResult(requestCode, resultCode, data);
19217e9e1933055b207473b488595b2887bfcaea32eJim Miller            switch (requestCode) {
19317e9e1933055b207473b488595b2887bfcaea32eJim Miller                case CONFIRM_EXISTING_REQUEST:
19417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (resultCode != Activity.RESULT_OK) {
19517e9e1933055b207473b488595b2887bfcaea32eJim Miller                        getActivity().setResult(RESULT_FINISHED);
19617e9e1933055b207473b488595b2887bfcaea32eJim Miller                        getActivity().finish();
197a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                    } else {
198a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                        mCurrentPattern = data.getStringExtra(
199a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                                ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
20017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
201a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales
20217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    updateStage(Stage.Introduction);
20317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
204afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
20517e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
206afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
207af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        protected void setRightButtonEnabled(boolean enabled) {
208af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            mFooterRightButton.setEnabled(enabled);
209af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        }
210af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam
211af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        protected void setRightButtonText(int text) {
212af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            mFooterRightButton.setText(text);
213af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        }
214af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam
21517e9e1933055b207473b488595b2887bfcaea32eJim Miller        /**
21617e9e1933055b207473b488595b2887bfcaea32eJim Miller         * The pattern listener that responds according to a user choosing a new
21717e9e1933055b207473b488595b2887bfcaea32eJim Miller         * lock pattern.
21817e9e1933055b207473b488595b2887bfcaea32eJim Miller         */
21917e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected LockPatternView.OnPatternListener mChooseNewLockPatternListener =
22017e9e1933055b207473b488595b2887bfcaea32eJim Miller                new LockPatternView.OnPatternListener() {
22117e9e1933055b207473b488595b2887bfcaea32eJim Miller
22217e9e1933055b207473b488595b2887bfcaea32eJim Miller                public void onPatternStart() {
22317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.removeCallbacks(mClearPatternRunnable);
22417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    patternInProgress();
225afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
226afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
22717e9e1933055b207473b488595b2887bfcaea32eJim Miller                public void onPatternCleared() {
22817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.removeCallbacks(mClearPatternRunnable);
22917e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
23056544d0e9198ab21dabec621cdf419b52b412dacJim Miller
23117e9e1933055b207473b488595b2887bfcaea32eJim Miller                public void onPatternDetected(List<LockPatternView.Cell> pattern) {
23217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (mUiStage == Stage.NeedToConfirm || mUiStage == Stage.ConfirmWrong) {
23317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        if (mChosenPattern == null) throw new IllegalStateException(
23417e9e1933055b207473b488595b2887bfcaea32eJim Miller                                "null chosen pattern in stage 'need to confirm");
23517e9e1933055b207473b488595b2887bfcaea32eJim Miller                        if (mChosenPattern.equals(pattern)) {
23617e9e1933055b207473b488595b2887bfcaea32eJim Miller                            updateStage(Stage.ChoiceConfirmed);
23717e9e1933055b207473b488595b2887bfcaea32eJim Miller                        } else {
23817e9e1933055b207473b488595b2887bfcaea32eJim Miller                            updateStage(Stage.ConfirmWrong);
23917e9e1933055b207473b488595b2887bfcaea32eJim Miller                        }
24017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else if (mUiStage == Stage.Introduction || mUiStage == Stage.ChoiceTooShort){
24117e9e1933055b207473b488595b2887bfcaea32eJim Miller                        if (pattern.size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
24217e9e1933055b207473b488595b2887bfcaea32eJim Miller                            updateStage(Stage.ChoiceTooShort);
24317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        } else {
24417e9e1933055b207473b488595b2887bfcaea32eJim Miller                            mChosenPattern = new ArrayList<LockPatternView.Cell>(pattern);
24517e9e1933055b207473b488595b2887bfcaea32eJim Miller                            updateStage(Stage.FirstChoiceValid);
24617e9e1933055b207473b488595b2887bfcaea32eJim Miller                        }
24717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else {
24817e9e1933055b207473b488595b2887bfcaea32eJim Miller                        throw new IllegalStateException("Unexpected stage " + mUiStage + " when "
24917e9e1933055b207473b488595b2887bfcaea32eJim Miller                                + "entering the pattern.");
25017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
25117e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
25256544d0e9198ab21dabec621cdf419b52b412dacJim Miller
25317e9e1933055b207473b488595b2887bfcaea32eJim Miller                public void onPatternCellAdded(List<Cell> pattern) {
254afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
25517e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
256afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
25717e9e1933055b207473b488595b2887bfcaea32eJim Miller                private void patternInProgress() {
25817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mHeaderText.setText(R.string.lockpattern_recording_inprogress);
25917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mFooterText.setText("");
26017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mFooterLeftButton.setEnabled(false);
26117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mFooterRightButton.setEnabled(false);
262011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei
263011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                    if (mTitleHeaderScrollView != null) {
264011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                        mTitleHeaderScrollView.post(new Runnable() {
265011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                            @Override
266011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                            public void run() {
267011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                                mTitleHeaderScrollView.fullScroll(ScrollView.FOCUS_DOWN);
268011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                            }
269011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                        });
270011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                    }
27117e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
27217e9e1933055b207473b488595b2887bfcaea32eJim Miller         };
273afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
2748a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren        @Override
2756507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang        public int getMetricsCategory() {
2769d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wren            return MetricsEvent.CHOOSE_LOCK_PATTERN;
2778a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren        }
2788a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren
279afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
280afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /**
28117e9e1933055b207473b488595b2887bfcaea32eJim Miller         * The states of the left footer button.
282afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
28317e9e1933055b207473b488595b2887bfcaea32eJim Miller        enum LeftButtonMode {
28417e9e1933055b207473b488595b2887bfcaea32eJim Miller            Cancel(R.string.cancel, true),
28517e9e1933055b207473b488595b2887bfcaea32eJim Miller            CancelDisabled(R.string.cancel, false),
28617e9e1933055b207473b488595b2887bfcaea32eJim Miller            Retry(R.string.lockpattern_retry_button_text, true),
28717e9e1933055b207473b488595b2887bfcaea32eJim Miller            RetryDisabled(R.string.lockpattern_retry_button_text, false),
28817e9e1933055b207473b488595b2887bfcaea32eJim Miller            Gone(ID_EMPTY_MESSAGE, false);
28917e9e1933055b207473b488595b2887bfcaea32eJim Miller
29017e9e1933055b207473b488595b2887bfcaea32eJim Miller
29117e9e1933055b207473b488595b2887bfcaea32eJim Miller            /**
29217e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param text The displayed text for this mode.
29317e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param enabled Whether the button should be enabled.
29417e9e1933055b207473b488595b2887bfcaea32eJim Miller             */
29517e9e1933055b207473b488595b2887bfcaea32eJim Miller            LeftButtonMode(int text, boolean enabled) {
29617e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.text = text;
29717e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.enabled = enabled;
29817e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
299afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
30017e9e1933055b207473b488595b2887bfcaea32eJim Miller            final int text;
30117e9e1933055b207473b488595b2887bfcaea32eJim Miller            final boolean enabled;
30217e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
303afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
304afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /**
30517e9e1933055b207473b488595b2887bfcaea32eJim Miller         * The states of the right button.
306afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
30717e9e1933055b207473b488595b2887bfcaea32eJim Miller        enum RightButtonMode {
308c57b19d80c100bb4a19bb2d4b8589bc12cbfd66eMaurice Lam            Continue(R.string.next_label, true),
309c57b19d80c100bb4a19bb2d4b8589bc12cbfd66eMaurice Lam            ContinueDisabled(R.string.next_label, false),
31017e9e1933055b207473b488595b2887bfcaea32eJim Miller            Confirm(R.string.lockpattern_confirm_button_text, true),
31117e9e1933055b207473b488595b2887bfcaea32eJim Miller            ConfirmDisabled(R.string.lockpattern_confirm_button_text, false),
31217e9e1933055b207473b488595b2887bfcaea32eJim Miller            Ok(android.R.string.ok, true);
31317e9e1933055b207473b488595b2887bfcaea32eJim Miller
31417e9e1933055b207473b488595b2887bfcaea32eJim Miller            /**
31517e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param text The displayed text for this mode.
31617e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param enabled Whether the button should be enabled.
31717e9e1933055b207473b488595b2887bfcaea32eJim Miller             */
31817e9e1933055b207473b488595b2887bfcaea32eJim Miller            RightButtonMode(int text, boolean enabled) {
31917e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.text = text;
32017e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.enabled = enabled;
32117e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
322afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
32317e9e1933055b207473b488595b2887bfcaea32eJim Miller            final int text;
32417e9e1933055b207473b488595b2887bfcaea32eJim Miller            final boolean enabled;
32517e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
326afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
327afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /**
32817e9e1933055b207473b488595b2887bfcaea32eJim Miller         * Keep track internally of where the user is in choosing a pattern.
329afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
33017e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected enum Stage {
33117e9e1933055b207473b488595b2887bfcaea32eJim Miller
33217e9e1933055b207473b488595b2887bfcaea32eJim Miller            Introduction(
33317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_recording_intro_header,
33417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Cancel, RightButtonMode.ContinueDisabled,
33563cf89a49a751c49bf60b9898e7d59f02b91c046Jim Miller                    ID_EMPTY_MESSAGE, true),
33617e9e1933055b207473b488595b2887bfcaea32eJim Miller            HelpScreen(
33717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_settings_help_how_to_record,
33817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Gone, RightButtonMode.Ok, ID_EMPTY_MESSAGE, false),
33917e9e1933055b207473b488595b2887bfcaea32eJim Miller            ChoiceTooShort(
34017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_recording_incorrect_too_short,
34117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Retry, RightButtonMode.ContinueDisabled,
34217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    ID_EMPTY_MESSAGE, true),
34317e9e1933055b207473b488595b2887bfcaea32eJim Miller            FirstChoiceValid(
34417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_pattern_entered_header,
34517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Retry, RightButtonMode.Continue, ID_EMPTY_MESSAGE, false),
34617e9e1933055b207473b488595b2887bfcaea32eJim Miller            NeedToConfirm(
34717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_need_to_confirm,
34877cb854d689cd5c49e14f80abb7803d77ced2e79Jim Miller                    LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
34917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    ID_EMPTY_MESSAGE, true),
35017e9e1933055b207473b488595b2887bfcaea32eJim Miller            ConfirmWrong(
35117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_need_to_unlock_wrong,
35217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
35317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    ID_EMPTY_MESSAGE, true),
35417e9e1933055b207473b488595b2887bfcaea32eJim Miller            ChoiceConfirmed(
35517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.string.lockpattern_pattern_confirmed_header,
35617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode.Cancel, RightButtonMode.Confirm, ID_EMPTY_MESSAGE, false);
35717e9e1933055b207473b488595b2887bfcaea32eJim Miller
35817e9e1933055b207473b488595b2887bfcaea32eJim Miller
35917e9e1933055b207473b488595b2887bfcaea32eJim Miller            /**
36017e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param headerMessage The message displayed at the top.
36117e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param leftMode The mode of the left button.
36217e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param rightMode The mode of the right button.
36317e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param footerMessage The footer message.
36417e9e1933055b207473b488595b2887bfcaea32eJim Miller             * @param patternEnabled Whether the pattern widget is enabled.
36517e9e1933055b207473b488595b2887bfcaea32eJim Miller             */
36617e9e1933055b207473b488595b2887bfcaea32eJim Miller            Stage(int headerMessage,
36717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    LeftButtonMode leftMode,
36817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    RightButtonMode rightMode,
36917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    int footerMessage, boolean patternEnabled) {
37017e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.headerMessage = headerMessage;
37117e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.leftMode = leftMode;
37217e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.rightMode = rightMode;
37317e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.footerMessage = footerMessage;
37417e9e1933055b207473b488595b2887bfcaea32eJim Miller                this.patternEnabled = patternEnabled;
37517e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
37617e9e1933055b207473b488595b2887bfcaea32eJim Miller
37717e9e1933055b207473b488595b2887bfcaea32eJim Miller            final int headerMessage;
37817e9e1933055b207473b488595b2887bfcaea32eJim Miller            final LeftButtonMode leftMode;
37917e9e1933055b207473b488595b2887bfcaea32eJim Miller            final RightButtonMode rightMode;
38017e9e1933055b207473b488595b2887bfcaea32eJim Miller            final int footerMessage;
38117e9e1933055b207473b488595b2887bfcaea32eJim Miller            final boolean patternEnabled;
382afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
383afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
38417e9e1933055b207473b488595b2887bfcaea32eJim Miller        private Stage mUiStage = Stage.Introduction;
385afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
38617e9e1933055b207473b488595b2887bfcaea32eJim Miller        private Runnable mClearPatternRunnable = new Runnable() {
38717e9e1933055b207473b488595b2887bfcaea32eJim Miller            public void run() {
38817e9e1933055b207473b488595b2887bfcaea32eJim Miller                mLockPatternView.clearPattern();
38917e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
39017e9e1933055b207473b488595b2887bfcaea32eJim Miller        };
391afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
39217e9e1933055b207473b488595b2887bfcaea32eJim Miller        private ChooseLockSettingsHelper mChooseLockSettingsHelper;
3933e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private SaveAndFinishWorker mSaveAndFinishWorker;
394fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri        private int mUserId;
395afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
39617e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String KEY_UI_STAGE = "uiStage";
39717e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String KEY_PATTERN_CHOICE = "chosenPattern";
398a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales        private static final String KEY_CURRENT_PATTERN = "currentPattern";
39900d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
40017e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
40117e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onCreate(Bundle savedInstanceState) {
40217e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onCreate(savedInstanceState);
40317e9e1933055b207473b488595b2887bfcaea32eJim Miller            mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
40466026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani            if (!(getActivity() instanceof ChooseLockPattern)) {
40566026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani                throw new SecurityException("Fragment contained in wrong activity");
40666026773bbf1d7631743a5b892a4f768c694f868Amith Yamasani            }
407fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri            Intent intent = getActivity().getIntent();
408fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri            // Only take this argument into account if it belongs to the current profile.
409194300dff340d67255d12762ffb376b7ba201c87Benjamin Franz            mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras());
41062775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos
41162775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos            if (intent.getBooleanExtra(
41262775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                    ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) {
41362775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                SaveAndFinishWorker w = new SaveAndFinishWorker();
41462775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                final boolean required = getActivity().getIntent().getBooleanExtra(
41562775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                        EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
41662775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                String current = intent.getStringExtra(
41762775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                        ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
41862775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                w.setBlocking(true);
41962775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                w.setListener(this);
42062775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                w.start(mChooseLockSettingsHelper.utils(), required,
42162775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos                        false, 0, LockPatternUtils.stringToPattern(current), current, mUserId);
42262775bf756a8eca9423bb4fab3fc7b71ab22d1a7Adrian Roos            }
42392779ce70156031f4fa3b8c2d84305f5b3b44105Udam Saini            mHideDrawer = getActivity().getIntent().getBooleanExtra(EXTRA_HIDE_DRAWER, false);
42417e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
425afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
42617e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
42717e9e1933055b207473b488595b2887bfcaea32eJim Miller        public View onCreateView(LayoutInflater inflater, ViewGroup container,
42817e9e1933055b207473b488595b2887bfcaea32eJim Miller                Bundle savedInstanceState) {
429d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam            final GlifLayout layout = (GlifLayout) inflater.inflate(
430d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam                    R.layout.choose_lock_pattern, container, false);
431d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam            layout.setHeaderText(getActivity().getTitle());
432d189ac52a4e49291b729d817fc903116abc086d0Maurice Lam            return layout;
4336b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam        }
43417e9e1933055b207473b488595b2887bfcaea32eJim Miller
4356b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam        @Override
4366b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam        public void onViewCreated(View view, Bundle savedInstanceState) {
4376b19fa9017800b94c75238339a337fd8f6c3e808Maurice Lam            super.onViewCreated(view, savedInstanceState);
43817e9e1933055b207473b488595b2887bfcaea32eJim Miller            mHeaderText = (TextView) view.findViewById(R.id.headerText);
43917e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern);
44017e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
44117e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.setTactileFeedbackEnabled(
44217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mChooseLockSettingsHelper.utils().isTactileFeedbackEnabled());
44317e9e1933055b207473b488595b2887bfcaea32eJim Miller
44417e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterText = (TextView) view.findViewById(R.id.footerText);
44517e9e1933055b207473b488595b2887bfcaea32eJim Miller
44617e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterLeftButton = (TextView) view.findViewById(R.id.footerLeftButton);
44717e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterRightButton = (TextView) view.findViewById(R.id.footerRightButton);
44817e9e1933055b207473b488595b2887bfcaea32eJim Miller
449011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei            mTitleHeaderScrollView = (ScrollView) view.findViewById(R.id
450011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei                    .scroll_layout_title_header);
451011f0dbcdb4cce682905e7e4aa944497811e5885jackqdyulei
45217e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterLeftButton.setOnClickListener(this);
45317e9e1933055b207473b488595b2887bfcaea32eJim Miller            mFooterRightButton.setOnClickListener(this);
45417e9e1933055b207473b488595b2887bfcaea32eJim Miller
45517e9e1933055b207473b488595b2887bfcaea32eJim Miller            // make it so unhandled touch events within the unlock screen go to the
45617e9e1933055b207473b488595b2887bfcaea32eJim Miller            // lock pattern view.
45717e9e1933055b207473b488595b2887bfcaea32eJim Miller            final LinearLayoutWithDefaultTouchRecepient topLayout
45817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    = (LinearLayoutWithDefaultTouchRecepient) view.findViewById(
45917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    R.id.topLayout);
46017e9e1933055b207473b488595b2887bfcaea32eJim Miller            topLayout.setDefaultTouchRecepient(mLockPatternView);
46117e9e1933055b207473b488595b2887bfcaea32eJim Miller
46217e9e1933055b207473b488595b2887bfcaea32eJim Miller            final boolean confirmCredentials = getActivity().getIntent()
4632eb170cd6ff43db01dc0ff3c1fcac5ebba4489deMaurice Lam                    .getBooleanExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, true);
4646609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales            Intent intent = getActivity().getIntent();
4656609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales            mCurrentPattern = intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
4666609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales            mHasChallenge = intent.getBooleanExtra(
4676609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales                    ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
4686609b0c22ae89a24d1b07dc3c4143452616d4450Andres Morales            mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
46917e9e1933055b207473b488595b2887bfcaea32eJim Miller
47017e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (savedInstanceState == null) {
47117e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (confirmCredentials) {
47217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    // first launch. As a security measure, we're in NeedToConfirm mode until we
47317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    // know there isn't an existing password or the user confirms their password.
47417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    updateStage(Stage.NeedToConfirm);
47517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    boolean launchedConfirmationActivity =
47617e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mChooseLockSettingsHelper.launchConfirmationActivity(
4778a09b619aeb233e2aab1919301f162d8acf1f0f0Jorim Jaggi                                CONFIRM_EXISTING_REQUEST,
478fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri                                getString(R.string.unlock_set_unlock_launch_picker_title), true,
479fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri                                mUserId);
48017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (!launchedConfirmationActivity) {
48117e9e1933055b207473b488595b2887bfcaea32eJim Miller                        updateStage(Stage.Introduction);
48217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
48317e9e1933055b207473b488595b2887bfcaea32eJim Miller                } else {
484bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                    updateStage(Stage.Introduction);
485bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                }
486bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller            } else {
48717e9e1933055b207473b488595b2887bfcaea32eJim Miller                // restore from previous state
48817e9e1933055b207473b488595b2887bfcaea32eJim Miller                final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE);
48917e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (patternString != null) {
49017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mChosenPattern = LockPatternUtils.stringToPattern(patternString);
49117e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
492a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales
493a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                if (mCurrentPattern == null) {
494a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                    mCurrentPattern = savedInstanceState.getString(KEY_CURRENT_PATTERN);
495a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                }
49617e9e1933055b207473b488595b2887bfcaea32eJim Miller                updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
4973e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
4983e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                // Re-attach to the exiting worker if there is one.
4993e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                mSaveAndFinishWorker = (SaveAndFinishWorker) getFragmentManager().findFragmentByTag(
5003e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                        FRAGMENT_TAG_SAVE_AND_FINISH);
501afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
502afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
503afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
504bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        @Override
505bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        public void onResume() {
506bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia            super.onResume();
507e47a2ab83eac80ed6e46606668db21b178168da7Xiyuan Xia            updateStage(mUiStage);
508e47a2ab83eac80ed6e46606668db21b178168da7Xiyuan Xia
5093e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (mSaveAndFinishWorker != null) {
5103e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                setRightButtonEnabled(false);
5113e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                mSaveAndFinishWorker.setListener(this);
5123e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            }
513bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        }
514bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia
515bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        @Override
516bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        public void onPause() {
517bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia            super.onPause();
5183e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (mSaveAndFinishWorker != null) {
5193e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                mSaveAndFinishWorker.setListener(null);
520bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia            }
521bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        }
522bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia
523ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam        protected Intent getRedactionInterstitialIntent(Context context) {
524f6077f4757183ae8b31af0928c895c806241b593Clara Bayarri            return RedactionInterstitial.createStartIntent(context, mUserId);
525ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam        }
526ecd2b7b81fd2faa2f2f3dbe5a169c749321f3d89Maurice Lam
527af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        public void handleLeftButton() {
528af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            if (mUiStage.leftMode == LeftButtonMode.Retry) {
529af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                mChosenPattern = null;
530af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                mLockPatternView.clearPattern();
531af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                updateStage(Stage.Introduction);
532af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            } else if (mUiStage.leftMode == LeftButtonMode.Cancel) {
533af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                getActivity().finish();
534af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            } else {
535af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                throw new IllegalStateException("left footer button pressed, but stage of " +
53617e9e1933055b207473b488595b2887bfcaea32eJim Miller                        mUiStage + " doesn't make sense");
537af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            }
538af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        }
53917e9e1933055b207473b488595b2887bfcaea32eJim Miller
540af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        public void handleRightButton() {
541af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            if (mUiStage.rightMode == RightButtonMode.Continue) {
542af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                if (mUiStage != Stage.FirstChoiceValid) {
543af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                    throw new IllegalStateException("expected ui stage "
544af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                            + Stage.FirstChoiceValid + " when button is "
545af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                            + RightButtonMode.Continue);
546af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                }
547af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                updateStage(Stage.NeedToConfirm);
548af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            } else if (mUiStage.rightMode == RightButtonMode.Confirm) {
549af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                if (mUiStage != Stage.ChoiceConfirmed) {
550af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                    throw new IllegalStateException("expected ui stage " + Stage.ChoiceConfirmed
551af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                            + " when button is " + RightButtonMode.Confirm);
552af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                }
5533e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                startSaveAndFinish();
554af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            } else if (mUiStage.rightMode == RightButtonMode.Ok) {
555af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                if (mUiStage != Stage.HelpScreen) {
556af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                    throw new IllegalStateException("Help screen is only mode with ok button, "
557af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                            + "but stage is " + mUiStage);
558afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
559af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                mLockPatternView.clearPattern();
560af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                mLockPatternView.setDisplayMode(DisplayMode.Correct);
561af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                updateStage(Stage.Introduction);
562af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            }
563af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        }
564af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam
565af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam        public void onClick(View v) {
566af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            if (v == mFooterLeftButton) {
567af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                handleLeftButton();
568af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            } else if (v == mFooterRightButton) {
569af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam                handleRightButton();
570afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
571afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
572afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
57317e9e1933055b207473b488595b2887bfcaea32eJim Miller        public boolean onKeyDown(int keyCode, KeyEvent event) {
57417e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
57517e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (mUiStage == Stage.HelpScreen) {
57617e9e1933055b207473b488595b2887bfcaea32eJim Miller                    updateStage(Stage.Introduction);
57717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    return true;
57817e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
57917e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
58017e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (keyCode == KeyEvent.KEYCODE_MENU && mUiStage == Stage.Introduction) {
58117e9e1933055b207473b488595b2887bfcaea32eJim Miller                updateStage(Stage.HelpScreen);
582afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return true;
583afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
58417e9e1933055b207473b488595b2887bfcaea32eJim Miller            return false;
585afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
586afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
58717e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onSaveInstanceState(Bundle outState) {
58817e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onSaveInstanceState(outState);
589afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
59017e9e1933055b207473b488595b2887bfcaea32eJim Miller            outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
59117e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (mChosenPattern != null) {
59217e9e1933055b207473b488595b2887bfcaea32eJim Miller                outState.putString(KEY_PATTERN_CHOICE,
59317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        LockPatternUtils.patternToString(mChosenPattern));
59417e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
595a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales
596a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales            if (mCurrentPattern != null) {
597a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                outState.putString(KEY_CURRENT_PATTERN,
598a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales                        mCurrentPattern);
599a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales            }
600afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
601afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
60217e9e1933055b207473b488595b2887bfcaea32eJim Miller        /**
60317e9e1933055b207473b488595b2887bfcaea32eJim Miller         * Updates the messages and buttons appropriate to what stage the user
60417e9e1933055b207473b488595b2887bfcaea32eJim Miller         * is at in choosing a view.  This doesn't handle clearing out the pattern;
60517e9e1933055b207473b488595b2887bfcaea32eJim Miller         * the pattern is expected to be in the right state.
60617e9e1933055b207473b488595b2887bfcaea32eJim Miller         * @param stage
60717e9e1933055b207473b488595b2887bfcaea32eJim Miller         */
60817e9e1933055b207473b488595b2887bfcaea32eJim Miller        protected void updateStage(Stage stage) {
609eef72c39ae83697b1beaa148ec56aced67382fecalanv            final Stage previousStage = mUiStage;
610afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
61117e9e1933055b207473b488595b2887bfcaea32eJim Miller            mUiStage = stage;
612afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
61317e9e1933055b207473b488595b2887bfcaea32eJim Miller            // header text, footer text, visibility and
61417e9e1933055b207473b488595b2887bfcaea32eJim Miller            // enabled state all known from the stage
61517e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (stage == Stage.ChoiceTooShort) {
61617e9e1933055b207473b488595b2887bfcaea32eJim Miller                mHeaderText.setText(
61717e9e1933055b207473b488595b2887bfcaea32eJim Miller                        getResources().getString(
61817e9e1933055b207473b488595b2887bfcaea32eJim Miller                                stage.headerMessage,
61917e9e1933055b207473b488595b2887bfcaea32eJim Miller                                LockPatternUtils.MIN_LOCK_PATTERN_SIZE));
62017e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
62117e9e1933055b207473b488595b2887bfcaea32eJim Miller                mHeaderText.setText(stage.headerMessage);
62217e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
62317e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (stage.footerMessage == ID_EMPTY_MESSAGE) {
62417e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterText.setText("");
62517e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
62617e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterText.setText(stage.footerMessage);
62717e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
628afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
62917e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (stage.leftMode == LeftButtonMode.Gone) {
63017e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterLeftButton.setVisibility(View.GONE);
63117e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
63217e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterLeftButton.setVisibility(View.VISIBLE);
63317e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterLeftButton.setText(stage.leftMode.text);
63417e9e1933055b207473b488595b2887bfcaea32eJim Miller                mFooterLeftButton.setEnabled(stage.leftMode.enabled);
63517e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
636afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
637af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            setRightButtonText(stage.rightMode.text);
638af103b4eb476881fb27cfb9b6dc94b3fa5e74f28Maurice Lam            setRightButtonEnabled(stage.rightMode.enabled);
639afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
6403e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            // same for whether the pattern is enabled
64117e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (stage.patternEnabled) {
64217e9e1933055b207473b488595b2887bfcaea32eJim Miller                mLockPatternView.enableInput();
64317e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
64417e9e1933055b207473b488595b2887bfcaea32eJim Miller                mLockPatternView.disableInput();
64517e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
646afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
64717e9e1933055b207473b488595b2887bfcaea32eJim Miller            // the rest of the stuff varies enough that it is easier just to handle
64817e9e1933055b207473b488595b2887bfcaea32eJim Miller            // on a case by case basis.
64917e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.setDisplayMode(DisplayMode.Correct);
65000da4f6d3b7cd2aa347b88e3f15b3b6ddd3e5803Selim Cinek            boolean announceAlways = false;
65117e9e1933055b207473b488595b2887bfcaea32eJim Miller
65217e9e1933055b207473b488595b2887bfcaea32eJim Miller            switch (mUiStage) {
65317e9e1933055b207473b488595b2887bfcaea32eJim Miller                case Introduction:
65417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.clearPattern();
65517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
65617e9e1933055b207473b488595b2887bfcaea32eJim Miller                case HelpScreen:
65717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.setPattern(DisplayMode.Animate, mAnimatePattern);
65817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
65917e9e1933055b207473b488595b2887bfcaea32eJim Miller                case ChoiceTooShort:
66017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.setDisplayMode(DisplayMode.Wrong);
66117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    postClearPatternRunnable();
66200da4f6d3b7cd2aa347b88e3f15b3b6ddd3e5803Selim Cinek                    announceAlways = true;
66317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
66417e9e1933055b207473b488595b2887bfcaea32eJim Miller                case FirstChoiceValid:
66517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
66617e9e1933055b207473b488595b2887bfcaea32eJim Miller                case NeedToConfirm:
66717e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.clearPattern();
66817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
66917e9e1933055b207473b488595b2887bfcaea32eJim Miller                case ConfirmWrong:
67017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mLockPatternView.setDisplayMode(DisplayMode.Wrong);
67117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    postClearPatternRunnable();
67200da4f6d3b7cd2aa347b88e3f15b3b6ddd3e5803Selim Cinek                    announceAlways = true;
67317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
67417e9e1933055b207473b488595b2887bfcaea32eJim Miller                case ChoiceConfirmed:
67517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    break;
67617e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
677eef72c39ae83697b1beaa148ec56aced67382fecalanv
678eef72c39ae83697b1beaa148ec56aced67382fecalanv            // If the stage changed, announce the header for accessibility. This
679eef72c39ae83697b1beaa148ec56aced67382fecalanv            // is a no-op when accessibility is disabled.
68000da4f6d3b7cd2aa347b88e3f15b3b6ddd3e5803Selim Cinek            if (previousStage != stage || announceAlways) {
681eef72c39ae83697b1beaa148ec56aced67382fecalanv                mHeaderText.announceForAccessibility(mHeaderText.getText());
682eef72c39ae83697b1beaa148ec56aced67382fecalanv            }
683afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
684afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
68517e9e1933055b207473b488595b2887bfcaea32eJim Miller        // clear the wrong pattern unless they have started a new one
68617e9e1933055b207473b488595b2887bfcaea32eJim Miller        // already
68717e9e1933055b207473b488595b2887bfcaea32eJim Miller        private void postClearPatternRunnable() {
68817e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.removeCallbacks(mClearPatternRunnable);
68917e9e1933055b207473b488595b2887bfcaea32eJim Miller            mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
69017e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
691afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
6923e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private void startSaveAndFinish() {
6933e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (mSaveAndFinishWorker != null) {
6943e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                Log.w(TAG, "startSaveAndFinish with an existing SaveAndFinishWorker.");
6953e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                return;
6963e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            }
697e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
6983e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            setRightButtonEnabled(false);
69990d6c568cf24178669254964af343f729639b31dAdrian Roos
7003e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            mSaveAndFinishWorker = new SaveAndFinishWorker();
7015bb1e4fb909a5f0e0574d3572ea1edcf32a2190fRobin Lee            mSaveAndFinishWorker.setListener(this);
7025bb1e4fb909a5f0e0574d3572ea1edcf32a2190fRobin Lee
7033e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            getFragmentManager().beginTransaction().add(mSaveAndFinishWorker,
7043e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                    FRAGMENT_TAG_SAVE_AND_FINISH).commit();
7055bb1e4fb909a5f0e0574d3572ea1edcf32a2190fRobin Lee            getFragmentManager().executePendingTransactions();
706cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence
7073e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            final boolean required = getActivity().getIntent().getBooleanExtra(
7080698a216311acd9ab52224602d1a75c08bf89f04Jim Miller                    EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
7093e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            mSaveAndFinishWorker.start(mChooseLockSettingsHelper.utils(), required,
710fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri                    mHasChallenge, mChallenge, mChosenPattern, mCurrentPattern, mUserId);
7113e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        }
712a0e1236fa970ea953bfbcc84fcae1f3fb7f189d1Andres Morales
7133e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        @Override
7143e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
7153e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            getActivity().setResult(RESULT_FINISHED, resultData);
716e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
7173e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (!wasSecureBefore) {
7183e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                Intent intent = getRedactionInterstitialIntent(getActivity());
7193e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                if (intent != null) {
72092779ce70156031f4fa3b8c2d84305f5b3b44105Udam Saini                    intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
7213e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                    startActivity(intent);
7223e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                }
72317e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
724686ae494f485a5025dfa456b4f32427b3715c337Udam Saini            getActivity().finish();
7253e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        }
7263e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia    }
72700d2476d8fc122b4eef59d6be6f7aa41e9c56fdeJim Miller
72877c4345373bdf6d6543bc06a04abc026ce762dbeClara Bayarri    public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
7293e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7303e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private List<LockPatternView.Cell> mChosenPattern;
7313e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private String mCurrentPattern;
7323e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        private boolean mLockVirgin;
7333e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7343e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        public void start(LockPatternUtils utils, boolean credentialRequired,
7353e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                boolean hasChallenge, long challenge,
736fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri                List<LockPatternView.Cell> chosenPattern, String currentPattern, int userId) {
737b8a22e42d42e6de8fce1a2026c112c12fd0f0f7aClara Bayarri            prepare(utils, credentialRequired, hasChallenge, challenge, userId);
7383e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7393e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            mCurrentPattern = currentPattern;
7403e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            mChosenPattern = chosenPattern;
741fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri            mUserId = userId;
7423e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
743fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri            mLockVirgin = !mUtils.isPatternEverChosen(mUserId);
7443e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7453e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            start();
7463e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        }
7473e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7483e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        @Override
7493e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        protected Intent saveAndVerifyInBackground() {
7503e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            Intent result = null;
751fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri            final int userId = mUserId;
7523e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            mUtils.saveLockPattern(mChosenPattern, mCurrentPattern, userId);
7533e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7543e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (mHasChallenge) {
7553e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                byte[] token;
7563e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                try {
7573e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                    token = mUtils.verifyPattern(mChosenPattern, mChallenge, userId);
7583e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                } catch (RequestThrottledException e) {
7593e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                    token = null;
760cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence                }
761cff37ecbdd4a3d8f9b81fc295155bde5fcf8ea0cPaul Lawrence
7623e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                if (token == null) {
7633e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                    Log.e(TAG, "critical: no token returned for known good pattern");
76458c5fb38c75cf04309f74927b3c91c54a645b690Jorim Jaggi                }
765bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia
7663e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                result = new Intent();
7673e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia                result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
768bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia            }
769bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia
7703e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            return result;
771bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia        }
772bf9ac6b4fb6428d0194a5163181b30cccaedb8ebXiyuan Xia
7733e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        @Override
7743e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia        protected void finish(Intent resultData) {
7753e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            if (mLockVirgin) {
776fe432e838e5588cd4ac664d7e74f3d70a99d7df1Clara Bayarri                mUtils.setVisiblePatternEnabled(true, mUserId);
7773e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            }
7783e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia
7793e7e3d6c594018e4bc7fc77acc19e148d8bf1bddXiyuan Xia            super.finish(resultData);
78017e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
781afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
782afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
783