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