19da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio/*
29da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio * Copyright (C) 2012 The Android Open Source Project
39da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio *
49da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License");
59da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio * you may not use this file except in compliance with the License.
69da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio * You may obtain a copy of the License at
79da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio *
89da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio *      http://www.apache.org/licenses/LICENSE-2.0
99da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio *
109da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio * Unless required by applicable law or agreed to in writing, software
119da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS,
129da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio * See the License for the specific language governing permissions and
149da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio * limitations under the License.
159da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio */
169da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio
179da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Megliopackage com.android.internal.policy.impl.keyguard;
189da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio
199da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport android.content.Context;
209da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport android.content.res.TypedArray;
219da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport android.text.SpannableStringBuilder;
229da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport android.text.style.TextAppearanceSpan;
239da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport android.util.AttributeSet;
249da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport android.view.HapticFeedbackConstants;
259da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport android.view.View;
269da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport android.widget.Button;
279da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport android.widget.TextView;
289da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio
299da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport com.android.internal.R;
309da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglioimport com.android.internal.widget.LockPatternUtils;
319da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio
32public class NumPadKey extends Button {
33    // list of "ABC", etc per digit, starting with '0'
34    static String sKlondike[];
35
36    int mDigit = -1;
37    int mTextViewResId;
38    TextView mTextView = null;
39    boolean mEnableHaptics;
40
41    private View.OnClickListener mListener = new View.OnClickListener() {
42        @Override
43        public void onClick(View thisView) {
44            if (mTextView == null) {
45                if (mTextViewResId > 0) {
46                    final View v = NumPadKey.this.getRootView().findViewById(mTextViewResId);
47                    if (v != null && v instanceof TextView) {
48                        mTextView = (TextView) v;
49                    }
50                }
51            }
52            // check for time-based lockouts
53            if (mTextView != null && mTextView.isEnabled()) {
54                mTextView.append(String.valueOf(mDigit));
55            }
56            doHapticKeyClick();
57        }
58    };
59
60    public NumPadKey(Context context) {
61        this(context, null);
62    }
63
64    public NumPadKey(Context context, AttributeSet attrs) {
65        this(context, attrs, 0);
66    }
67
68    public NumPadKey(Context context, AttributeSet attrs, int defStyle) {
69        super(context, attrs, defStyle);
70
71        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumPadKey);
72        mDigit = a.getInt(R.styleable.NumPadKey_digit, mDigit);
73        setTextViewResId(a.getResourceId(R.styleable.NumPadKey_textView, 0));
74
75        setOnClickListener(mListener);
76        setOnHoverListener(new LiftToActivateListener(context));
77        setAccessibilityDelegate(new ObscureSpeechDelegate(context));
78
79        mEnableHaptics = new LockPatternUtils(context).isTactileFeedbackEnabled();
80
81        SpannableStringBuilder builder = new SpannableStringBuilder();
82        builder.append(String.valueOf(mDigit));
83        if (mDigit >= 0) {
84            if (sKlondike == null) {
85                sKlondike = context.getResources().getStringArray(
86                        R.array.lockscreen_num_pad_klondike);
87            }
88            if (sKlondike != null && sKlondike.length > mDigit) {
89                final String extra = sKlondike[mDigit];
90                final int extraLen = extra.length();
91                if (extraLen > 0) {
92                    builder.append(" ");
93                    builder.append(extra);
94                    builder.setSpan(
95                        new TextAppearanceSpan(context, R.style.TextAppearance_NumPadKey_Klondike),
96                        builder.length()-extraLen, builder.length(), 0);
97                }
98            }
99        }
100        setText(builder);
101    }
102
103    @Override
104    public void onDetachedFromWindow() {
105        super.onDetachedFromWindow();
106
107        // Reset the "announced headset" flag when detached.
108        ObscureSpeechDelegate.sAnnouncedHeadset = false;
109    }
110
111    public void setTextView(TextView tv) {
112        mTextView = tv;
113    }
114
115    public void setTextViewResId(int resId) {
116        mTextView = null;
117        mTextViewResId = resId;
118    }
119
120    // Cause a VIRTUAL_KEY vibration
121    public void doHapticKeyClick() {
122        if (mEnableHaptics) {
123            performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
124                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
125                    | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
126        }
127    }
128}
129