KeyguardAbsKeyInputView.java revision 1254f2f42f7173ef51d0034975ab5cb7d44f8209
169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler/*
269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler * Copyright (C) 2012 The Android Open Source Project
369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler *
469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler * Licensed under the Apache License, Version 2.0 (the "License");
569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler * you may not use this file except in compliance with the License.
669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler * You may obtain a copy of the License at
769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler *
869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler *      http://www.apache.org/licenses/LICENSE-2.0
969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler *
1069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler * Unless required by applicable law or agreed to in writing, software
1169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler * distributed under the License is distributed on an "AS IS" BASIS,
1269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler * See the License for the specific language governing permissions and
1469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler * limitations under the License.
1569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler */
1669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
1769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerpackage com.android.internal.policy.impl.keyguard;
1869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
1969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.content.Context;
2069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.graphics.Rect;
2169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.os.CountDownTimer;
2269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.os.SystemClock;
2369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.text.Editable;
2469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.text.TextWatcher;
251254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurkaimport android.util.AttributeSet;
261254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurkaimport android.view.HapticFeedbackConstants;
2769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.view.KeyEvent;
281254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurkaimport android.view.View;
2969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.view.inputmethod.EditorInfo;
3069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.widget.LinearLayout;
3169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.widget.TextView;
3269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.widget.TextView.OnEditorActionListener;
3369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
3469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport com.android.internal.R;
351254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurkaimport com.android.internal.widget.LockPatternUtils;
3669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
3769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler/**
3869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler * Base class for PIN and password unlock screens.
3969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler */
4069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerpublic abstract class KeyguardAbsKeyInputView extends LinearLayout
4169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
4269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    protected KeyguardSecurityCallback mCallback;
43d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler    protected TextView mPasswordEntry;
4469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    protected LockPatternUtils mLockPatternUtils;
4569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    protected SecurityMessageDisplay mSecurityMessageDisplay;
46acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    protected boolean mEnableHaptics;
4769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
4869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    // To avoid accidental lockout due to events while the device in in the pocket, ignore
4969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    // any passwords with length less than or equal to this length.
5069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    protected static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3;
5169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
5269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public KeyguardAbsKeyInputView(Context context) {
5369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        this(context, null);
5469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
5569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
5669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public KeyguardAbsKeyInputView(Context context, AttributeSet attrs) {
5769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        super(context, attrs);
5869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
5969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
6069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
6169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mCallback = callback;
6269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
6369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
6469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void setLockPatternUtils(LockPatternUtils utils) {
6569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mLockPatternUtils = utils;
66acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler        mEnableHaptics = mLockPatternUtils.isTactileFeedbackEnabled();
6769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
6869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
6969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
7069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void onWindowFocusChanged(boolean hasWindowFocus) {
7169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        if (hasWindowFocus) {
7269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            reset();
7369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        }
7469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
7569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
7669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void reset() {
7769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        // start fresh
7869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mPasswordEntry.setText("");
7969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mPasswordEntry.requestFocus();
8069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
8169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        // if the user is currently locked out, enforce it.
8269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
8369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        if (deadline != 0) {
8469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            handleAttemptLockout(deadline);
8569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        } else {
8669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            resetState();
8769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        }
8869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
8969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
9069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    protected abstract void resetState();
9169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
9269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
9369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    protected void onFinishInflate() {
9469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        // We always set a dummy NavigationManager to avoid null checks
9569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mSecurityMessageDisplay = new KeyguardNavigationManager(null);
9669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
97acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler        mLockPatternUtils = new LockPatternUtils(mContext);
9869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
99d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler        mPasswordEntry = (TextView) findViewById(R.id.passwordEntry);
10069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mPasswordEntry.setOnEditorActionListener(this);
10169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mPasswordEntry.addTextChangedListener(this);
10269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
10369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        // Poke the wakelock any time the text is selected or modified
10469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mPasswordEntry.setOnClickListener(new OnClickListener() {
10569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            public void onClick(View v) {
10669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                mCallback.userActivity(0); // TODO: customize timeout for text?
10769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
10869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        });
10969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
11069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mPasswordEntry.addTextChangedListener(new TextWatcher() {
11169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            public void onTextChanged(CharSequence s, int start, int before, int count) {
11269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
11369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
11469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
11569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
11669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
11769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            public void afterTextChanged(Editable s) {
11869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                if (mCallback != null) {
11969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                    mCallback.userActivity(0);
12069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                }
12169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
12269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        });
12369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
12469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
12569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
12669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
12769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        // send focus to the password field
12869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
12969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
13069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
13169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    protected void verifyPasswordAndUnlock() {
13269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        String entry = mPasswordEntry.getText().toString();
13369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        if (mLockPatternUtils.checkPassword(entry)) {
13469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            mCallback.reportSuccessfulUnlockAttempt();
13569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            mCallback.dismiss(true);
13669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        } else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) {
13769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            // to avoid accidental lockout, only count attempts that are long enough to be a
13869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            // real password. This may require some tweaking.
13969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            mCallback.reportFailedUnlockAttempt();
14069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            if (0 == (mCallback.getFailedAttempts()
14169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                    % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
14269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
14369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                handleAttemptLockout(deadline);
14469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
14569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pin, true);
14669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        }
14769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mPasswordEntry.setText("");
14869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
14969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
15069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    // Prevent user from using the PIN/Password entry until scheduled deadline.
15169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    protected void handleAttemptLockout(long elapsedRealtimeDeadline) {
15269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mPasswordEntry.setEnabled(false);
15369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        long elapsedRealtime = SystemClock.elapsedRealtime();
15469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
15569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
15669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            @Override
15769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            public void onTick(long millisUntilFinished) {
15869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                int secondsRemaining = (int) (millisUntilFinished / 1000);
15969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                mSecurityMessageDisplay.setMessage(
16069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                        R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining);
16169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
16269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
16369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            @Override
16469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            public void onFinish() {
16569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                resetState();
16669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
16769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        }.start();
16869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
16969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
17069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
17169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public boolean onKeyDown(int keyCode, KeyEvent event) {
17269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mCallback.userActivity(0);
17369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        return false;
17469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
17569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
17669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
17769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
17869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        // Check if this was the result of hitting the enter key
17969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE
18069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                || actionId == EditorInfo.IME_ACTION_NEXT) {
18169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            verifyPasswordAndUnlock();
18269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            return true;
18369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        }
18469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        return false;
18569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
18669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
18769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
18869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public boolean needsInput() {
18969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        return false;
19069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
19169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
19269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
19369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void onPause() {
19469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
19569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
19669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
19769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
19869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void onResume() {
19969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        reset();
20069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
20169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
20269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
20369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public KeyguardSecurityCallback getCallback() {
20469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        return mCallback;
20569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
20669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
20769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
20869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
20969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        if (mCallback != null) {
21069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            mCallback.userActivity(KeyguardViewManager.DIGIT_PRESS_WAKE_MILLIS);
21169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        }
21269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
21369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
21469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
21569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void onTextChanged(CharSequence s, int start, int before, int count) {
21669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
21769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
21869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
21969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void afterTextChanged(Editable s) {
22069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
22169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
22269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    @Override
22369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
22469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mSecurityMessageDisplay = display;
22569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        reset();
22669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
227acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler
228acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    // Cause a VIRTUAL_KEY vibration
229acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    public void doHapticKeyClick() {
230acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler        if (mEnableHaptics) {
231acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler            performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
232acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
233acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler                    | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
234acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler        }
235acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    }
23669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler}
23769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
238