15b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen/*
25b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen * Copyright (C) 2013 The Android Open Source Project
35b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen *
45b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen * Licensed under the Apache License, Version 2.0 (the "License");
55b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen * you may not use this file except in compliance with the License.
65b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen * You may obtain a copy of the License at
75b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen *
85b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen *      http://www.apache.org/licenses/LICENSE-2.0
95b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen *
105b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen * Unless required by applicable law or agreed to in writing, software
115b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen * distributed under the License is distributed on an "AS IS" BASIS,
125b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen * See the License for the specific language governing permissions and
145b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen * limitations under the License
155b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen */
165b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
175b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenpackage com.android.incallui;
185b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
195b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenimport android.content.Context;
205b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenimport android.os.Bundle;
2157d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordonimport android.os.Handler;
2257d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordonimport android.os.Looper;
239939a07593e79192f2eafaf5791b308088fb2330Ihab Awadimport android.telephony.PhoneNumberUtils;
242c083a837265238b14580b20c4c327122b11a431Christine Chenimport android.text.Editable;
252c083a837265238b14580b20c4c327122b11a431Christine Chenimport android.text.method.DialerKeyListener;
26a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awadimport android.util.AttributeSet;
275b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenimport android.view.KeyEvent;
285b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenimport android.view.LayoutInflater;
295b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenimport android.view.MotionEvent;
305b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenimport android.view.View;
315b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenimport android.view.ViewGroup;
325b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenimport android.view.accessibility.AccessibilityManager;
335b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenimport android.widget.EditText;
34a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awadimport android.widget.LinearLayout;
35a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awadimport android.widget.TextView;
365b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
37062dd164b103fb5333689cab06544a1338916248Sai Cheemalapatiimport com.android.phone.common.dialpad.DialpadKeyButton;
38062dd164b103fb5333689cab06544a1338916248Sai Cheemalapatiimport com.android.phone.common.dialpad.DialpadView;
3973bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee
405b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chenimport java.util.HashMap;
415b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
425b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen/**
435b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen * Fragment for call control buttons
445b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen */
451fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Chengpublic class DialpadFragment extends BaseFragment<DialpadPresenter, DialpadPresenter.DialpadUi>
465b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        implements DialpadPresenter.DialpadUi, View.OnTouchListener, View.OnKeyListener,
475b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        View.OnHoverListener, View.OnClickListener {
485b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
4957d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon    private static final int ACCESSIBILITY_DTMF_STOP_DELAY_MILLIS = 50;
5057d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon
516c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen    private final int[] mButtonIds = new int[] {R.id.zero, R.id.one, R.id.two, R.id.three,
526c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen            R.id.four, R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.star,
536c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen            R.id.pound};
546c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen
55a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad    /**
56a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad     * LinearLayout with getter and setter methods for the translationY property using floats,
57a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad     * for animation purposes.
58a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad     */
59a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad    public static class DialpadSlidingLinearLayout extends LinearLayout {
60a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad
61a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad        public DialpadSlidingLinearLayout(Context context) {
62a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad            super(context);
63a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad        }
64a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad
65a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad        public DialpadSlidingLinearLayout(Context context, AttributeSet attrs) {
66a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad            super(context, attrs);
67a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad        }
68a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad
69a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad        public DialpadSlidingLinearLayout(Context context, AttributeSet attrs, int defStyle) {
70a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad            super(context, attrs, defStyle);
71a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad        }
72a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad
73a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad        public float getYFraction() {
74a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad            final int height = getHeight();
75a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad            if (height == 0) return 0;
76a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad            return getTranslationY() / height;
77a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad        }
78a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad
79a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad        public void setYFraction(float yFraction) {
80a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad            setTranslationY(yFraction * getHeight());
81a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad        }
82a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad    }
83a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad
845b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    private EditText mDtmfDialerField;
855b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
865b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    /** Hash Map to map a view id to a character*/
875b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    private static final HashMap<Integer, Character> mDisplayMap =
885b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        new HashMap<Integer, Character>();
895b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
9057d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon    private static final Handler sHandler = new Handler(Looper.getMainLooper());
9157d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon
9257d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon
935b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    /** Set up the static maps*/
945b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    static {
955b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        // Map the buttons to the display characters
965b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.one, '1');
975b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.two, '2');
985b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.three, '3');
995b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.four, '4');
1005b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.five, '5');
1015b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.six, '6');
1025b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.seven, '7');
1035b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.eight, '8');
1045b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.nine, '9');
1055b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.zero, '0');
1065b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.pound, '#');
1075b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        mDisplayMap.put(R.id.star, '*');
1085b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
1095b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
1102c083a837265238b14580b20c4c327122b11a431Christine Chen    // KeyListener used with the "dialpad digits" EditText widget.
1112c083a837265238b14580b20c4c327122b11a431Christine Chen    private DTMFKeyListener mDialerKeyListener;
1122c083a837265238b14580b20c4c327122b11a431Christine Chen
11373bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee    private DialpadView mDialpadView;
11473bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee
1156c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen    private int mCurrentTextColor;
1166c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen
1172c083a837265238b14580b20c4c327122b11a431Christine Chen    /**
1182c083a837265238b14580b20c4c327122b11a431Christine Chen     * Our own key listener, specialized for dealing with DTMF codes.
1192c083a837265238b14580b20c4c327122b11a431Christine Chen     *   1. Ignore the backspace since it is irrelevant.
1202c083a837265238b14580b20c4c327122b11a431Christine Chen     *   2. Allow ONLY valid DTMF characters to generate a tone and be
1212c083a837265238b14580b20c4c327122b11a431Christine Chen     *      sent as a DTMF code.
1222c083a837265238b14580b20c4c327122b11a431Christine Chen     *   3. All other remaining characters are handled by the superclass.
1232c083a837265238b14580b20c4c327122b11a431Christine Chen     *
1242c083a837265238b14580b20c4c327122b11a431Christine Chen     * This code is purely here to handle events from the hardware keyboard
1252c083a837265238b14580b20c4c327122b11a431Christine Chen     * while the DTMF dialpad is up.
1262c083a837265238b14580b20c4c327122b11a431Christine Chen     */
1272c083a837265238b14580b20c4c327122b11a431Christine Chen    private class DTMFKeyListener extends DialerKeyListener {
1282c083a837265238b14580b20c4c327122b11a431Christine Chen
1292c083a837265238b14580b20c4c327122b11a431Christine Chen        private DTMFKeyListener() {
1302c083a837265238b14580b20c4c327122b11a431Christine Chen            super();
1312c083a837265238b14580b20c4c327122b11a431Christine Chen        }
1322c083a837265238b14580b20c4c327122b11a431Christine Chen
1332c083a837265238b14580b20c4c327122b11a431Christine Chen        /**
1342c083a837265238b14580b20c4c327122b11a431Christine Chen         * Overriden to return correct DTMF-dialable characters.
1352c083a837265238b14580b20c4c327122b11a431Christine Chen         */
1362c083a837265238b14580b20c4c327122b11a431Christine Chen        @Override
1372c083a837265238b14580b20c4c327122b11a431Christine Chen        protected char[] getAcceptedChars(){
1382c083a837265238b14580b20c4c327122b11a431Christine Chen            return DTMF_CHARACTERS;
1392c083a837265238b14580b20c4c327122b11a431Christine Chen        }
1402c083a837265238b14580b20c4c327122b11a431Christine Chen
1412c083a837265238b14580b20c4c327122b11a431Christine Chen        /** special key listener ignores backspace. */
1422c083a837265238b14580b20c4c327122b11a431Christine Chen        @Override
1432c083a837265238b14580b20c4c327122b11a431Christine Chen        public boolean backspace(View view, Editable content, int keyCode,
1442c083a837265238b14580b20c4c327122b11a431Christine Chen                KeyEvent event) {
1452c083a837265238b14580b20c4c327122b11a431Christine Chen            return false;
1462c083a837265238b14580b20c4c327122b11a431Christine Chen        }
1472c083a837265238b14580b20c4c327122b11a431Christine Chen
1482c083a837265238b14580b20c4c327122b11a431Christine Chen        /**
1492c083a837265238b14580b20c4c327122b11a431Christine Chen         * Return true if the keyCode is an accepted modifier key for the
1502c083a837265238b14580b20c4c327122b11a431Christine Chen         * dialer (ALT or SHIFT).
1512c083a837265238b14580b20c4c327122b11a431Christine Chen         */
1522c083a837265238b14580b20c4c327122b11a431Christine Chen        private boolean isAcceptableModifierKey(int keyCode) {
1532c083a837265238b14580b20c4c327122b11a431Christine Chen            switch (keyCode) {
1542c083a837265238b14580b20c4c327122b11a431Christine Chen                case KeyEvent.KEYCODE_ALT_LEFT:
1552c083a837265238b14580b20c4c327122b11a431Christine Chen                case KeyEvent.KEYCODE_ALT_RIGHT:
1562c083a837265238b14580b20c4c327122b11a431Christine Chen                case KeyEvent.KEYCODE_SHIFT_LEFT:
1572c083a837265238b14580b20c4c327122b11a431Christine Chen                case KeyEvent.KEYCODE_SHIFT_RIGHT:
1582c083a837265238b14580b20c4c327122b11a431Christine Chen                    return true;
1592c083a837265238b14580b20c4c327122b11a431Christine Chen                default:
1602c083a837265238b14580b20c4c327122b11a431Christine Chen                    return false;
1612c083a837265238b14580b20c4c327122b11a431Christine Chen            }
1622c083a837265238b14580b20c4c327122b11a431Christine Chen        }
1632c083a837265238b14580b20c4c327122b11a431Christine Chen
1642c083a837265238b14580b20c4c327122b11a431Christine Chen        /**
1652c083a837265238b14580b20c4c327122b11a431Christine Chen         * Overriden so that with each valid button press, we start sending
1662c083a837265238b14580b20c4c327122b11a431Christine Chen         * a dtmf code and play a local dtmf tone.
1672c083a837265238b14580b20c4c327122b11a431Christine Chen         */
1682c083a837265238b14580b20c4c327122b11a431Christine Chen        @Override
1692c083a837265238b14580b20c4c327122b11a431Christine Chen        public boolean onKeyDown(View view, Editable content,
1702c083a837265238b14580b20c4c327122b11a431Christine Chen                                 int keyCode, KeyEvent event) {
1712c083a837265238b14580b20c4c327122b11a431Christine Chen            // if (DBG) log("DTMFKeyListener.onKeyDown, keyCode " + keyCode + ", view " + view);
1722c083a837265238b14580b20c4c327122b11a431Christine Chen
1732c083a837265238b14580b20c4c327122b11a431Christine Chen            // find the character
1742c083a837265238b14580b20c4c327122b11a431Christine Chen            char c = (char) lookup(event, content);
1752c083a837265238b14580b20c4c327122b11a431Christine Chen
1762c083a837265238b14580b20c4c327122b11a431Christine Chen            // if not a long press, and parent onKeyDown accepts the input
1772c083a837265238b14580b20c4c327122b11a431Christine Chen            if (event.getRepeatCount() == 0 && super.onKeyDown(view, content, keyCode, event)) {
1782c083a837265238b14580b20c4c327122b11a431Christine Chen
1792c083a837265238b14580b20c4c327122b11a431Christine Chen                boolean keyOK = ok(getAcceptedChars(), c);
1802c083a837265238b14580b20c4c327122b11a431Christine Chen
1812c083a837265238b14580b20c4c327122b11a431Christine Chen                // if the character is a valid dtmf code, start playing the tone and send the
1822c083a837265238b14580b20c4c327122b11a431Christine Chen                // code.
1832c083a837265238b14580b20c4c327122b11a431Christine Chen                if (keyOK) {
1842c083a837265238b14580b20c4c327122b11a431Christine Chen                    Log.d(this, "DTMFKeyListener reading '" + c + "' from input.");
1852c083a837265238b14580b20c4c327122b11a431Christine Chen                    getPresenter().processDtmf(c);
1862c083a837265238b14580b20c4c327122b11a431Christine Chen                } else {
1872c083a837265238b14580b20c4c327122b11a431Christine Chen                    Log.d(this, "DTMFKeyListener rejecting '" + c + "' from input.");
1882c083a837265238b14580b20c4c327122b11a431Christine Chen                }
1892c083a837265238b14580b20c4c327122b11a431Christine Chen                return true;
1902c083a837265238b14580b20c4c327122b11a431Christine Chen            }
1912c083a837265238b14580b20c4c327122b11a431Christine Chen            return false;
1922c083a837265238b14580b20c4c327122b11a431Christine Chen        }
1932c083a837265238b14580b20c4c327122b11a431Christine Chen
1942c083a837265238b14580b20c4c327122b11a431Christine Chen        /**
1952c083a837265238b14580b20c4c327122b11a431Christine Chen         * Overriden so that with each valid button up, we stop sending
1962c083a837265238b14580b20c4c327122b11a431Christine Chen         * a dtmf code and the dtmf tone.
1972c083a837265238b14580b20c4c327122b11a431Christine Chen         */
1982c083a837265238b14580b20c4c327122b11a431Christine Chen        @Override
1992c083a837265238b14580b20c4c327122b11a431Christine Chen        public boolean onKeyUp(View view, Editable content,
2002c083a837265238b14580b20c4c327122b11a431Christine Chen                                 int keyCode, KeyEvent event) {
2012c083a837265238b14580b20c4c327122b11a431Christine Chen            // if (DBG) log("DTMFKeyListener.onKeyUp, keyCode " + keyCode + ", view " + view);
2022c083a837265238b14580b20c4c327122b11a431Christine Chen
2032c083a837265238b14580b20c4c327122b11a431Christine Chen            super.onKeyUp(view, content, keyCode, event);
2042c083a837265238b14580b20c4c327122b11a431Christine Chen
2052c083a837265238b14580b20c4c327122b11a431Christine Chen            // find the character
2062c083a837265238b14580b20c4c327122b11a431Christine Chen            char c = (char) lookup(event, content);
2072c083a837265238b14580b20c4c327122b11a431Christine Chen
2082c083a837265238b14580b20c4c327122b11a431Christine Chen            boolean keyOK = ok(getAcceptedChars(), c);
2092c083a837265238b14580b20c4c327122b11a431Christine Chen
2102c083a837265238b14580b20c4c327122b11a431Christine Chen            if (keyOK) {
2112c083a837265238b14580b20c4c327122b11a431Christine Chen                Log.d(this, "Stopping the tone for '" + c + "'");
21257d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon                getPresenter().stopDtmf();
2132c083a837265238b14580b20c4c327122b11a431Christine Chen                return true;
2142c083a837265238b14580b20c4c327122b11a431Christine Chen            }
2152c083a837265238b14580b20c4c327122b11a431Christine Chen
2162c083a837265238b14580b20c4c327122b11a431Christine Chen            return false;
2172c083a837265238b14580b20c4c327122b11a431Christine Chen        }
2182c083a837265238b14580b20c4c327122b11a431Christine Chen
2192c083a837265238b14580b20c4c327122b11a431Christine Chen        /**
2202c083a837265238b14580b20c4c327122b11a431Christine Chen         * Handle individual keydown events when we DO NOT have an Editable handy.
2212c083a837265238b14580b20c4c327122b11a431Christine Chen         */
2222c083a837265238b14580b20c4c327122b11a431Christine Chen        public boolean onKeyDown(KeyEvent event) {
2232c083a837265238b14580b20c4c327122b11a431Christine Chen            char c = lookup(event);
2242c083a837265238b14580b20c4c327122b11a431Christine Chen            Log.d(this, "DTMFKeyListener.onKeyDown: event '" + c + "'");
2252c083a837265238b14580b20c4c327122b11a431Christine Chen
2262c083a837265238b14580b20c4c327122b11a431Christine Chen            // if not a long press, and parent onKeyDown accepts the input
2272c083a837265238b14580b20c4c327122b11a431Christine Chen            if (event.getRepeatCount() == 0 && c != 0) {
2282c083a837265238b14580b20c4c327122b11a431Christine Chen                // if the character is a valid dtmf code, start playing the tone and send the
2292c083a837265238b14580b20c4c327122b11a431Christine Chen                // code.
2302c083a837265238b14580b20c4c327122b11a431Christine Chen                if (ok(getAcceptedChars(), c)) {
2312c083a837265238b14580b20c4c327122b11a431Christine Chen                    Log.d(this, "DTMFKeyListener reading '" + c + "' from input.");
2322c083a837265238b14580b20c4c327122b11a431Christine Chen                    getPresenter().processDtmf(c);
2332c083a837265238b14580b20c4c327122b11a431Christine Chen                    return true;
2342c083a837265238b14580b20c4c327122b11a431Christine Chen                } else {
2352c083a837265238b14580b20c4c327122b11a431Christine Chen                    Log.d(this, "DTMFKeyListener rejecting '" + c + "' from input.");
2362c083a837265238b14580b20c4c327122b11a431Christine Chen                }
2372c083a837265238b14580b20c4c327122b11a431Christine Chen            }
2382c083a837265238b14580b20c4c327122b11a431Christine Chen            return false;
2392c083a837265238b14580b20c4c327122b11a431Christine Chen        }
2402c083a837265238b14580b20c4c327122b11a431Christine Chen
2412c083a837265238b14580b20c4c327122b11a431Christine Chen        /**
2422c083a837265238b14580b20c4c327122b11a431Christine Chen         * Handle individual keyup events.
2432c083a837265238b14580b20c4c327122b11a431Christine Chen         *
2442c083a837265238b14580b20c4c327122b11a431Christine Chen         * @param event is the event we are trying to stop.  If this is null,
2452c083a837265238b14580b20c4c327122b11a431Christine Chen         * then we just force-stop the last tone without checking if the event
2462c083a837265238b14580b20c4c327122b11a431Christine Chen         * is an acceptable dialer event.
2472c083a837265238b14580b20c4c327122b11a431Christine Chen         */
2482c083a837265238b14580b20c4c327122b11a431Christine Chen        public boolean onKeyUp(KeyEvent event) {
2492c083a837265238b14580b20c4c327122b11a431Christine Chen            if (event == null) {
2502c083a837265238b14580b20c4c327122b11a431Christine Chen                //the below piece of code sends stopDTMF event unnecessarily even when a null event
2512c083a837265238b14580b20c4c327122b11a431Christine Chen                //is received, hence commenting it.
2522c083a837265238b14580b20c4c327122b11a431Christine Chen                /*if (DBG) log("Stopping the last played tone.");
2532c083a837265238b14580b20c4c327122b11a431Christine Chen                stopTone();*/
2542c083a837265238b14580b20c4c327122b11a431Christine Chen                return true;
2552c083a837265238b14580b20c4c327122b11a431Christine Chen            }
2562c083a837265238b14580b20c4c327122b11a431Christine Chen
2572c083a837265238b14580b20c4c327122b11a431Christine Chen            char c = lookup(event);
2582c083a837265238b14580b20c4c327122b11a431Christine Chen            Log.d(this, "DTMFKeyListener.onKeyUp: event '" + c + "'");
2592c083a837265238b14580b20c4c327122b11a431Christine Chen
2602c083a837265238b14580b20c4c327122b11a431Christine Chen            // TODO: stopTone does not take in character input, we may want to
2612c083a837265238b14580b20c4c327122b11a431Christine Chen            // consider checking for this ourselves.
2622c083a837265238b14580b20c4c327122b11a431Christine Chen            if (ok(getAcceptedChars(), c)) {
2632c083a837265238b14580b20c4c327122b11a431Christine Chen                Log.d(this, "Stopping the tone for '" + c + "'");
26457d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon                getPresenter().stopDtmf();
2652c083a837265238b14580b20c4c327122b11a431Christine Chen                return true;
2662c083a837265238b14580b20c4c327122b11a431Christine Chen            }
2672c083a837265238b14580b20c4c327122b11a431Christine Chen
2682c083a837265238b14580b20c4c327122b11a431Christine Chen            return false;
2692c083a837265238b14580b20c4c327122b11a431Christine Chen        }
2702c083a837265238b14580b20c4c327122b11a431Christine Chen
2712c083a837265238b14580b20c4c327122b11a431Christine Chen        /**
2722c083a837265238b14580b20c4c327122b11a431Christine Chen         * Find the Dialer Key mapped to this event.
2732c083a837265238b14580b20c4c327122b11a431Christine Chen         *
2742c083a837265238b14580b20c4c327122b11a431Christine Chen         * @return The char value of the input event, otherwise
2752c083a837265238b14580b20c4c327122b11a431Christine Chen         * 0 if no matching character was found.
2762c083a837265238b14580b20c4c327122b11a431Christine Chen         */
2772c083a837265238b14580b20c4c327122b11a431Christine Chen        private char lookup(KeyEvent event) {
2782c083a837265238b14580b20c4c327122b11a431Christine Chen            // This code is similar to {@link DialerKeyListener#lookup(KeyEvent, Spannable) lookup}
2792c083a837265238b14580b20c4c327122b11a431Christine Chen            int meta = event.getMetaState();
2802c083a837265238b14580b20c4c327122b11a431Christine Chen            int number = event.getNumber();
2812c083a837265238b14580b20c4c327122b11a431Christine Chen
2822c083a837265238b14580b20c4c327122b11a431Christine Chen            if (!((meta & (KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)) == 0) || (number == 0)) {
2832c083a837265238b14580b20c4c327122b11a431Christine Chen                int match = event.getMatch(getAcceptedChars(), meta);
2842c083a837265238b14580b20c4c327122b11a431Christine Chen                number = (match != 0) ? match : number;
2852c083a837265238b14580b20c4c327122b11a431Christine Chen            }
2862c083a837265238b14580b20c4c327122b11a431Christine Chen
2872c083a837265238b14580b20c4c327122b11a431Christine Chen            return (char) number;
2882c083a837265238b14580b20c4c327122b11a431Christine Chen        }
2892c083a837265238b14580b20c4c327122b11a431Christine Chen
2902c083a837265238b14580b20c4c327122b11a431Christine Chen        /**
2912c083a837265238b14580b20c4c327122b11a431Christine Chen         * Check to see if the keyEvent is dialable.
2922c083a837265238b14580b20c4c327122b11a431Christine Chen         */
2932c083a837265238b14580b20c4c327122b11a431Christine Chen        boolean isKeyEventAcceptable (KeyEvent event) {
2942c083a837265238b14580b20c4c327122b11a431Christine Chen            return (ok(getAcceptedChars(), lookup(event)));
2952c083a837265238b14580b20c4c327122b11a431Christine Chen        }
2962c083a837265238b14580b20c4c327122b11a431Christine Chen
2972c083a837265238b14580b20c4c327122b11a431Christine Chen        /**
2982c083a837265238b14580b20c4c327122b11a431Christine Chen         * Overrides the characters used in {@link DialerKeyListener#CHARACTERS}
2992c083a837265238b14580b20c4c327122b11a431Christine Chen         * These are the valid dtmf characters.
3002c083a837265238b14580b20c4c327122b11a431Christine Chen         */
3012c083a837265238b14580b20c4c327122b11a431Christine Chen        public final char[] DTMF_CHARACTERS = new char[] {
3022c083a837265238b14580b20c4c327122b11a431Christine Chen            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '*'
3032c083a837265238b14580b20c4c327122b11a431Christine Chen        };
3042c083a837265238b14580b20c4c327122b11a431Christine Chen    }
3052c083a837265238b14580b20c4c327122b11a431Christine Chen
3065b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    @Override
3075b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    public void onClick(View v) {
3085b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        final AccessibilityManager accessibilityManager = (AccessibilityManager)
309c09452d2e855cbaed44d67388636f32feadf0991Yorke Lee            v.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
3105b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        // When accessibility is on, simulate press and release to preserve the
3115b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        // semantic meaning of performClick(). Required for Braille support.
3125b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        if (accessibilityManager.isEnabled()) {
3135b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            final int id = v.getId();
3145b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // Checking the press state prevents double activation.
3155b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            if (!v.isPressed() && mDisplayMap.containsKey(id)) {
316a81f411886922b08320c7bbaaa398a4506added0Evan Charlton                getPresenter().processDtmf(mDisplayMap.get(id));
31757d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon                sHandler.postDelayed(new Runnable() {
31857d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon                    @Override
31957d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon                    public void run() {
32057d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon                        getPresenter().stopDtmf();
32157d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon                    }
32257d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon                }, ACCESSIBILITY_DTMF_STOP_DELAY_MILLIS);
3235b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            }
3245b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        }
3255b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
3265b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
3275b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    @Override
3285b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    public boolean onHover(View v, MotionEvent event) {
3295b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        // When touch exploration is turned on, lifting a finger while inside
3305b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        // the button's hover target bounds should perform a click action.
3315b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        final AccessibilityManager accessibilityManager = (AccessibilityManager)
332c09452d2e855cbaed44d67388636f32feadf0991Yorke Lee            v.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
3335b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
3345b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        if (accessibilityManager.isEnabled()
3355b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                && accessibilityManager.isTouchExplorationEnabled()) {
3365b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            final int left = v.getPaddingLeft();
3375b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            final int right = (v.getWidth() - v.getPaddingRight());
3385b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            final int top = v.getPaddingTop();
3395b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            final int bottom = (v.getHeight() - v.getPaddingBottom());
3405b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
3415b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            switch (event.getActionMasked()) {
3425b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                case MotionEvent.ACTION_HOVER_ENTER:
3435b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    // Lift-to-type temporarily disables double-tap activation.
3445b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    v.setClickable(false);
3455b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    break;
3465b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                case MotionEvent.ACTION_HOVER_EXIT:
3475b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    final int x = (int) event.getX();
3485b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    final int y = (int) event.getY();
3495b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    if ((x > left) && (x < right) && (y > top) && (y < bottom)) {
3505b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                        v.performClick();
3515b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    }
3525b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    v.setClickable(true);
3535b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    break;
3545b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            }
3555b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        }
3565b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
3575b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        return false;
3585b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
3595b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
3605b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    @Override
3615b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    public boolean onKey(View v, int keyCode, KeyEvent event) {
3621a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "onKey:  keyCode " + keyCode + ", view " + v);
3635b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
3645b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
3655b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            int viewId = v.getId();
3665b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            if (mDisplayMap.containsKey(viewId)) {
3675b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                switch (event.getAction()) {
3685b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                case KeyEvent.ACTION_DOWN:
3695b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    if (event.getRepeatCount() == 0) {
3705b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                        getPresenter().processDtmf(mDisplayMap.get(viewId));
3715b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    }
3725b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    break;
3735b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                case KeyEvent.ACTION_UP:
37457d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon                    getPresenter().stopDtmf();
3755b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    break;
3765b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                }
3775b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                // do not return true [handled] here, since we want the
3785b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                // press / click animation to be handled by the framework.
3795b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            }
3805b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        }
3815b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        return false;
3825b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
3835b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
3845b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    @Override
3855b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    public boolean onTouch(View v, MotionEvent event) {
3861a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "onTouch");
3875b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        int viewId = v.getId();
3885b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
3895b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        // if the button is recognized
3905b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        if (mDisplayMap.containsKey(viewId)) {
3915b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            switch (event.getAction()) {
3925b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                case MotionEvent.ACTION_DOWN:
3935b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    // Append the character mapped to this button, to the display.
3945b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    // start the tone
3955b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    getPresenter().processDtmf(mDisplayMap.get(viewId));
3965b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    break;
3975b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                case MotionEvent.ACTION_UP:
3985b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                case MotionEvent.ACTION_CANCEL:
3995b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    // stop the tone on ANY other event, except for MOVE.
40057d98887da3799f2c88877cde3234c3069c7d9ffSantos Cordon                    getPresenter().stopDtmf();
4015b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen                    break;
4025b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            }
4035b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // do not return true [handled] here, since we want the
4045b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // press / click animation to be handled by the framework.
4055b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        }
4065b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        return false;
4075b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
4085b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
4095b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    // TODO(klp) Adds hardware keyboard listener
4105b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
4115b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    @Override
41245f2a7014de8102479a50886300fecbd704779a4Andrew Lee    public DialpadPresenter createPresenter() {
4135b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        return new DialpadPresenter();
4145b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
4155b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
4165b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    @Override
41745f2a7014de8102479a50886300fecbd704779a4Andrew Lee    public DialpadPresenter.DialpadUi getUi() {
4181fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng        return this;
4191fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng    }
4201fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng
4211fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng    @Override
4225b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    public View onCreateView(LayoutInflater inflater, ViewGroup container,
4235b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            Bundle savedInstanceState) {
4245b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        final View parent = inflater.inflate(
425bec5807b74a13e43a59b5a8b4a0b23c497315458Yorke Lee                R.layout.incall_dialpad_fragment, container, false);
42673bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee        mDialpadView = (DialpadView) parent.findViewById(R.id.dialpad_view);
42773bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee        mDialpadView.setCanDigitsBeEdited(false);
42873bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee        mDialpadView.setBackgroundResource(R.color.incall_dialpad_background);
42973bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee        mDtmfDialerField = (EditText) parent.findViewById(R.id.digits);
4305b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        if (mDtmfDialerField != null) {
4312c083a837265238b14580b20c4c327122b11a431Christine Chen            mDialerKeyListener = new DTMFKeyListener();
4322c083a837265238b14580b20c4c327122b11a431Christine Chen            mDtmfDialerField.setKeyListener(mDialerKeyListener);
4335b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // remove the long-press context menus that support
4345b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // the edit (copy / paste / select) functions.
4355b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            mDtmfDialerField.setLongClickable(false);
43673bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee            mDtmfDialerField.setElegantTextHeight(false);
4376c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen            configureKeypadListeners();
4385b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        }
439a389ad358b723ce1725662c79bfc175ddc2e558cIhab Awad
4405b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        return parent;
4415b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
4425b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
4435b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    @Override
4446c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen    public void onResume() {
4456c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen        super.onResume();
4466c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen        updateColors();
4476c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen    }
4486c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen
4496c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen    public void updateColors() {
4506c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen        int textColor = InCallPresenter.getInstance().getThemeColors().mPrimaryColor;
4516c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen
4526c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen        if (mCurrentTextColor == textColor) {
4536c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen            return;
4546c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen        }
4556c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen
4566c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen        DialpadKeyButton dialpadKey;
4576c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen        for (int i = 0; i < mButtonIds.length; i++) {
4586c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen            dialpadKey = (DialpadKeyButton) mDialpadView.findViewById(mButtonIds[i]);
4596c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen            ((TextView) dialpadKey.findViewById(R.id.dialpad_key_number)).setTextColor(textColor);
4606c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen        }
4616c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen
4626c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen        mCurrentTextColor = textColor;
4636c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen    }
4646c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen
4656c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen    @Override
4662c083a837265238b14580b20c4c327122b11a431Christine Chen    public void onDestroyView() {
4672c083a837265238b14580b20c4c327122b11a431Christine Chen        mDialerKeyListener = null;
4682c083a837265238b14580b20c4c327122b11a431Christine Chen        super.onDestroyView();
4692c083a837265238b14580b20c4c327122b11a431Christine Chen    }
4702c083a837265238b14580b20c4c327122b11a431Christine Chen
4714b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati    /**
4724b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati     * Getter for Dialpad text.
4734b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati     *
4744b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati     * @return String containing current Dialpad EditText text.
4754b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati     */
4764b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati    public String getDtmfText() {
4774b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati        return mDtmfDialerField.getText().toString();
4784b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati    }
4794b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati
4804b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati    /**
4814b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati     * Sets the Dialpad text field with some text.
4824b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati     *
4834b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati     * @param text Text to set Dialpad EditText to.
4844b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati     */
4854b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati    public void setDtmfText(String text) {
486867abc05df88949d953e0130d340909bfd4d78c7Brian Attwell        mDtmfDialerField.setText(PhoneNumberUtils.createTtsSpannable(text));
4874b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati    }
4884b2f53948580c0b984c2fae4ed174f2e9228a6acSai Cheemalapati
4892c083a837265238b14580b20c4c327122b11a431Christine Chen    @Override
4905b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    public void setVisible(boolean on) {
4915b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        if (on) {
4925b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            getView().setVisibility(View.VISIBLE);
4935b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        } else {
4945b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            getView().setVisibility(View.INVISIBLE);
4955b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        }
4965b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
4975b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
498fc3c903fcc1cb3187b5d7c26ad463395fbe1e167Sai Cheemalapati    /**
499fc3c903fcc1cb3187b5d7c26ad463395fbe1e167Sai Cheemalapati     * Starts the slide up animation for the Dialpad keys when the Dialpad is revealed.
500fc3c903fcc1cb3187b5d7c26ad463395fbe1e167Sai Cheemalapati     */
501fc3c903fcc1cb3187b5d7c26ad463395fbe1e167Sai Cheemalapati    public void animateShowDialpad() {
502fc3c903fcc1cb3187b5d7c26ad463395fbe1e167Sai Cheemalapati        final DialpadView dialpadView = (DialpadView) getView().findViewById(R.id.dialpad_view);
503fc3c903fcc1cb3187b5d7c26ad463395fbe1e167Sai Cheemalapati        dialpadView.animateShow();
504dd79f815edd15d5ccea31c10ee5dd8f3b5873d05Andrew Lee    }
505dd79f815edd15d5ccea31c10ee5dd8f3b5873d05Andrew Lee
506dd79f815edd15d5ccea31c10ee5dd8f3b5873d05Andrew Lee    @Override
5075b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    public void appendDigitsToField(char digit) {
5085b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        if (mDtmfDialerField != null) {
5095b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // TODO: maybe *don't* manually append this digit if
5105b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // mDialpadDigits is focused and this key came from the HW
5115b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // keyboard, since in that case the EditText field will
5125b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // get the key event directly and automatically appends
5135b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // whetever the user types.
5145b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // (Or, a cleaner fix would be to just make mDialpadDigits
5155b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // *not* handle HW key presses.  That seems to be more
5165b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // complicated than just setting focusable="false" on it,
5175b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            // though.)
5185b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen            mDtmfDialerField.getText().append(digit);
5195b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        }
5205b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
5215b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen
5225b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    /**
5232c083a837265238b14580b20c4c327122b11a431Christine Chen     * Called externally (from InCallScreen) to play a DTMF Tone.
5242c083a837265238b14580b20c4c327122b11a431Christine Chen     */
5252c083a837265238b14580b20c4c327122b11a431Christine Chen    /* package */ boolean onDialerKeyDown(KeyEvent event) {
5262c083a837265238b14580b20c4c327122b11a431Christine Chen        Log.d(this, "Notifying dtmf key down.");
5272c083a837265238b14580b20c4c327122b11a431Christine Chen        if (mDialerKeyListener != null) {
5282c083a837265238b14580b20c4c327122b11a431Christine Chen            return mDialerKeyListener.onKeyDown(event);
5292c083a837265238b14580b20c4c327122b11a431Christine Chen        } else {
5302c083a837265238b14580b20c4c327122b11a431Christine Chen            return false;
5312c083a837265238b14580b20c4c327122b11a431Christine Chen        }
5322c083a837265238b14580b20c4c327122b11a431Christine Chen    }
5332c083a837265238b14580b20c4c327122b11a431Christine Chen
5342c083a837265238b14580b20c4c327122b11a431Christine Chen    /**
5352c083a837265238b14580b20c4c327122b11a431Christine Chen     * Called externally (from InCallScreen) to cancel the last DTMF Tone played.
5362c083a837265238b14580b20c4c327122b11a431Christine Chen     */
5372c083a837265238b14580b20c4c327122b11a431Christine Chen    public boolean onDialerKeyUp(KeyEvent event) {
5382c083a837265238b14580b20c4c327122b11a431Christine Chen        Log.d(this, "Notifying dtmf key up.");
5392c083a837265238b14580b20c4c327122b11a431Christine Chen        if (mDialerKeyListener != null) {
5402c083a837265238b14580b20c4c327122b11a431Christine Chen            return mDialerKeyListener.onKeyUp(event);
5412c083a837265238b14580b20c4c327122b11a431Christine Chen        } else {
5422c083a837265238b14580b20c4c327122b11a431Christine Chen            return false;
5432c083a837265238b14580b20c4c327122b11a431Christine Chen        }
5442c083a837265238b14580b20c4c327122b11a431Christine Chen    }
5452c083a837265238b14580b20c4c327122b11a431Christine Chen
5466c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen    private void configureKeypadListeners() {
54773bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee        DialpadKeyButton dialpadKey;
5486c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen        for (int i = 0; i < mButtonIds.length; i++) {
5496c1e0d8809bc084bd081a23b48d09e095a615348Nancy Chen            dialpadKey = (DialpadKeyButton) mDialpadView.findViewById(mButtonIds[i]);
55073bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee            dialpadKey.setOnTouchListener(this);
55173bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee            dialpadKey.setOnKeyListener(this);
55273bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee            dialpadKey.setOnHoverListener(this);
55373bcc4b1cc19bf5b1d2a1f913789f012e8dd0d7eYorke Lee            dialpadKey.setOnClickListener(this);
5545b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen        }
5555b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen    }
5565b9034b5b1b48a4339dd2f893a851cc64d6279dfChristine Chen}
557