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.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
2969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerimport com.android.internal.R;
30acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandlerimport com.android.internal.widget.LockPatternUtils;
3169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
3269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerpublic class NumPadKey extends Button {
33d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler    // list of "ABC", etc per digit, starting with '0'
34d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler    static String sKlondike[];
3569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
3669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    int mDigit = -1;
3769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    int mTextViewResId;
3869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    TextView mTextView = null;
39acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    boolean mEnableHaptics;
4069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
4169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    private View.OnClickListener mListener = new View.OnClickListener() {
4269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        @Override
4369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        public void onClick(View thisView) {
4469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            if (mTextView == null) {
4569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                if (mTextViewResId > 0) {
4669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                    final View v = NumPadKey.this.getRootView().findViewById(mTextViewResId);
4769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                    if (v != null && v instanceof TextView) {
4869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                        mTextView = (TextView) v;
4969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                    }
5069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                }
5169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
526a64ac56b7a8b81e6f24b5ad9856185488f4178dDaniel Sandler            // check for time-based lockouts
536a64ac56b7a8b81e6f24b5ad9856185488f4178dDaniel Sandler            if (mTextView != null && mTextView.isEnabled()) {
5469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                mTextView.append(String.valueOf(mDigit));
5569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
56acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler            doHapticKeyClick();
5769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        }
5869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    };
5969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
6069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public NumPadKey(Context context) {
6169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        this(context, null);
6269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
6369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
6469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public NumPadKey(Context context, AttributeSet attrs) {
6569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        this(context, attrs, 0);
6669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
6769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
6869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public NumPadKey(Context context, AttributeSet attrs, int defStyle) {
6969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        super(context, attrs, defStyle);
7069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
7169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumPadKey);
7269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mDigit = a.getInt(R.styleable.NumPadKey_digit, mDigit);
7369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        setTextViewResId(a.getResourceId(R.styleable.NumPadKey_textView, 0));
7469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
7569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        setOnClickListener(mListener);
76c7375afef77b29b7fdb25f48dbe649b7b7fd487calanv        setOnHoverListener(new LiftToActivateListener(context));
770cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv        setAccessibilityDelegate(new ObscureSpeechDelegate(context));
7869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
79acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler        mEnableHaptics = new LockPatternUtils(context).isTactileFeedbackEnabled();
80acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler
8169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        SpannableStringBuilder builder = new SpannableStringBuilder();
8269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        builder.append(String.valueOf(mDigit));
8369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        if (mDigit >= 0) {
84d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler            if (sKlondike == null) {
85d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                sKlondike = context.getResources().getStringArray(
86d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                        R.array.lockscreen_num_pad_klondike);
87d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler            }
88d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler            if (sKlondike != null && sKlondike.length > mDigit) {
89d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                final String extra = sKlondike[mDigit];
90d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                final int extraLen = extra.length();
91d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                if (extraLen > 0) {
9280bc85a7916713aae0b49e06b4b63bb3760a7a39Daniel Sandler                    builder.append(" ");
93d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                    builder.append(extra);
94d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                    builder.setSpan(
95d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                        new TextAppearanceSpan(context, R.style.TextAppearance_NumPadKey_Klondike),
9669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                        builder.length()-extraLen, builder.length(), 0);
97d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler                }
9869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            }
9969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        }
10069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        setText(builder);
10169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
10269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
1030cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv    @Override
1040cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv    public void onDetachedFromWindow() {
1050cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv        super.onDetachedFromWindow();
1060cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv
1070cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv        // Reset the "announced headset" flag when detached.
1080cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv        ObscureSpeechDelegate.sAnnouncedHeadset = false;
1090cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv    }
1100cbbc5766fb7c56c49ec55eece905fa7764a8b2balanv
11169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void setTextView(TextView tv) {
11269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mTextView = tv;
11369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
11469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
11569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    public void setTextViewResId(int resId) {
11669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mTextView = null;
11769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mTextViewResId = resId;
11869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    }
119acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler
120acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    // Cause a VIRTUAL_KEY vibration
121acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    public void doHapticKeyClick() {
122acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler        if (mEnableHaptics) {
123acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler            performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
124acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
125acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler                    | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
126acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler        }
127acb60fb57783b517e52fa60b1fa5f977141180c1Daniel Sandler    }
128d5692742c1ff056e9fe55a495632229c86ed5384Daniel Sandler}
129