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
175ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerpackage com.android.keyguard;
1869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
1969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.content.Context;
2069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.content.res.TypedArray;
2169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.text.SpannableStringBuilder;
2269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.text.style.TextAppearanceSpan;
2369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.util.AttributeSet;
24acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandlerimport android.view.HapticFeedbackConstants;
2569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.view.View;
2669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.widget.Button;
2769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport android.widget.TextView;
2869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
29acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandlerimport com.android.internal.widget.LockPatternUtils;
3069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
3169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerpublic class NumPadKey extends Button {
32d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler    // list of "ABC", etc per digit, starting with '0'
33d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler    static String sKlondike[];
3469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
3569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    int mDigit = -1;
3669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    int mTextViewResId;
3769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    TextView mTextView = null;
38acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    boolean mEnableHaptics;
3969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
4069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    private View.OnClickListener mListener = new View.OnClickListener() {
4169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        @Override
4269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        public void onClick(View thisView) {
4369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            if (mTextView == null) {
4469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                if (mTextViewResId > 0) {
4569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                    final View v = NumPadKey.this.getRootView().findViewById(mTextViewResId);
4669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                    if (v != null && v instanceof TextView) {
4769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                        mTextView = (TextView) v;
4869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                    }
4969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                }
5069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
516a64ac56b7a8b81e6f24b5ad9856185488f4178dDaniel Sandler            // check for time-based lockouts
526a64ac56b7a8b81e6f24b5ad9856185488f4178dDaniel Sandler            if (mTextView != null && mTextView.isEnabled()) {
5369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                mTextView.append(String.valueOf(mDigit));
5469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
55acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler            doHapticKeyClick();
5669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        }
5769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    };
5869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
5969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public NumPadKey(Context context) {
6069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        this(context, null);
6169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
6269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
6369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public NumPadKey(Context context, AttributeSet attrs) {
6469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        this(context, attrs, 0);
6569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
6669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
6769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public NumPadKey(Context context, AttributeSet attrs, int defStyle) {
6869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        super(context, attrs, defStyle);
6969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
7069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumPadKey);
7169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mDigit = a.getInt(R.styleable.NumPadKey_digit, mDigit);
7269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        setTextViewResId(a.getResourceId(R.styleable.NumPadKey_textView, 0));
7369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
7469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        setOnClickListener(mListener);
75c7375afef77b29b7fdb25f48dbe649b7b7fd487calanv        setOnHoverListener(new LiftToActivateListener(context));
760cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv        setAccessibilityDelegate(new ObscureSpeechDelegate(context));
7769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
78acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler        mEnableHaptics = new LockPatternUtils(context).isTactileFeedbackEnabled();
79acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler
8069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        SpannableStringBuilder builder = new SpannableStringBuilder();
8169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        builder.append(String.valueOf(mDigit));
8269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        if (mDigit >= 0) {
83d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler            if (sKlondike == null) {
84d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                sKlondike = context.getResources().getStringArray(
85d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                        R.array.lockscreen_num_pad_klondike);
86d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler            }
87d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler            if (sKlondike != null && sKlondike.length > mDigit) {
88d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                final String extra = sKlondike[mDigit];
89d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                final int extraLen = extra.length();
90d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                if (extraLen > 0) {
9180bc85a7916713aae0b49e06b4b63bb3760a7a39Daniel Sandler                    builder.append(" ");
92d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                    builder.append(extra);
93d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                    builder.setSpan(
94d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                        new TextAppearanceSpan(context, R.style.TextAppearance_NumPadKey_Klondike),
9569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                        builder.length()-extraLen, builder.length(), 0);
96d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                }
9769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
9869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        }
9969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        setText(builder);
10069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
10169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
1020cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv    @Override
1030cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv    public void onDetachedFromWindow() {
1040cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv        super.onDetachedFromWindow();
1050cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv
1060cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv        // Reset the "announced headset" flag when detached.
1070cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv        ObscureSpeechDelegate.sAnnouncedHeadset = false;
1080cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv    }
1090cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv
11069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void setTextView(TextView tv) {
11169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mTextView = tv;
11269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
11369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
11469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void setTextViewResId(int resId) {
11569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mTextView = null;
11669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mTextViewResId = resId;
11769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
118acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler
119acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    // Cause a VIRTUAL_KEY vibration
120acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    public void doHapticKeyClick() {
121acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler        if (mEnableHaptics) {
122acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler            performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
123acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
124acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler                    | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
125acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler        }
126acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    }
127d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler}
128