DTMFTwelveKeyDialer.java revision 404edc94de563aef5fd5ba48be9114a970cb93bb
1b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/*
2b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project *
4b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * you may not use this file except in compliance with the License.
6b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * You may obtain a copy of the License at
7b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project *
8b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project *
10b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * See the License for the specific language governing permissions and
14b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * limitations under the License.
15b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */
16b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
17b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpackage com.android.phone;
18b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
19b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.media.AudioManager;
20b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.media.ToneGenerator;
21b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.Handler;
22b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.Message;
23b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.provider.Settings;
24b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.telephony.PhoneNumberUtils;
25b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.Editable;
26b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.Spannable;
27b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.method.DialerKeyListener;
28b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.method.MovementMethod;
29b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.Log;
30b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.KeyEvent;
31b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.MotionEvent;
32b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.View;
33b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.WindowManager;
34b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.animation.AlphaAnimation;
35b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.animation.Animation;
36b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.animation.Animation.AnimationListener;
37b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.animation.AnimationUtils;
38b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.EditText;
39b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.SlidingDrawer;
40b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.TextView;
41b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
42b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.CallerInfo;
43b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.CallerInfoAsyncQuery;
44b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.Phone;
45b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
46b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport java.util.HashMap;
47b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
48b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/**
49b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Dialer class that encapsulates the DTMF twelve key behaviour.
50b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This model backs up the UI behaviour in DTMFTwelveKeyDialerView.java.
51b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */
52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class DTMFTwelveKeyDialer implements
53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        CallerInfoAsyncQuery.OnQueryCompleteListener,
54b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        SlidingDrawer.OnDrawerOpenListener,
55b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        SlidingDrawer.OnDrawerCloseListener,
56b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        View.OnTouchListener,
57b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        View.OnKeyListener {
58b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final String LOG_TAG = "DTMFTwelveKeyDialer";
59796c70c99bc39295bf685061056f06ab8949c742David Brown    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
60b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
61b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // events
62b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final int PHONE_DISCONNECT = 100;
63b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
64bd6ef6be5bbece60afee7f1ef0a6bba732298dacDavid Brown    private Phone mPhone;
65b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ToneGenerator mToneGenerator;
66b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private Object mToneGeneratorLock = new Object();
67b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
68b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // indicate if we want to enable the DTMF tone playback.
69b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private boolean mDTMFToneEnabled;
70b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
71b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** Hash Map to map a character to a tone*/
72b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final HashMap<Character, Integer> mToneMap =
73b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        new HashMap<Character, Integer>();
74b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** Hash Map to map a view id to a character*/
75b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final HashMap<Integer, Character> mDisplayMap =
76b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        new HashMap<Integer, Character>();
77b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** Set up the static maps*/
78b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static {
79b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Map the key characters to tones
80b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('1', ToneGenerator.TONE_DTMF_1);
81b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('2', ToneGenerator.TONE_DTMF_2);
82b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('3', ToneGenerator.TONE_DTMF_3);
83b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('4', ToneGenerator.TONE_DTMF_4);
84b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('5', ToneGenerator.TONE_DTMF_5);
85b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('6', ToneGenerator.TONE_DTMF_6);
86b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('7', ToneGenerator.TONE_DTMF_7);
87b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('8', ToneGenerator.TONE_DTMF_8);
88b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('9', ToneGenerator.TONE_DTMF_9);
89b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('0', ToneGenerator.TONE_DTMF_0);
90b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('#', ToneGenerator.TONE_DTMF_P);
91b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('*', ToneGenerator.TONE_DTMF_S);
92b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
93b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Map the buttons to the display characters
94b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.one, '1');
95b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.two, '2');
96b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.three, '3');
97b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.four, '4');
98b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.five, '5');
99b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.six, '6');
100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.seven, '7');
101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.eight, '8');
102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.nine, '9');
103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.zero, '0');
104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.pound, '#');
105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.star, '*');
106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // EditText field used to display the DTMF digits sent so far.
109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // - In portrait mode, we use the EditText that comes from
110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    //   the full dialpad:
111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private EditText mDialpadDigits;
112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // - In landscape mode, we use a different EditText that's
113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    //   built into the InCallScreen:
114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private EditText mInCallDigits;
115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // (Only one of these will be visible at any given point.)
116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // InCallScreen reference.
118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private InCallScreen mInCallScreen;
119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // SlidingDrawer reference.
121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private SlidingDrawer mDialerContainer;
122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // view reference
124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private DTMFTwelveKeyDialerView mDialerView;
125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // key listner reference, may or may not be attached to a view.
127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private DTMFKeyListener mDialerKeyListener;
128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Create an input method just so that the textview can display the cursor.
131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * There is no selecting / positioning on the dialer field, only number input.
132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
133bd6ef6be5bbece60afee7f1ef0a6bba732298dacDavid Brown    private static class DTMFDisplayMovementMethod implements MovementMethod {
134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Return false since we are NOT consuming the input.*/
136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyDown(TextView widget, Spannable buffer, int keyCode, KeyEvent event) {
137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
140b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Return false since we are NOT consuming the input.*/
141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode, KeyEvent event) {
142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Return false since we are NOT consuming the input.*/
146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {
147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Return false since we are NOT consuming the input.*/
151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onTrackballEvent(TextView widget, Spannable buffer, MotionEvent event) {
152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Return false since we are NOT consuming the input.*/
156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public void initialize(TextView widget, Spannable text) {
161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public void onTakeFocus(TextView view, Spannable text, int dir) {
164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Disallow arbitrary selection.*/
167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean canSelectArbitrarily() {
168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Our own key listener, specialized for dealing with DTMF codes.
174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   1. Ignore the backspace since it is irrelevant.
175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   2. Allow ONLY valid DTMF characters to generate a tone and be
176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *      sent as a DTMF code.
177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   3. All other remaining characters are handled by the superclass.
178b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private class DTMFKeyListener extends DialerKeyListener {
180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        private DTMFDisplayAnimation mDTMFDisplayAnimation;
182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Class that controls the fade in/out of the DTMF dialer field.
185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Logic is tied into the keystroke events handled by the
186b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * DTMFKeyListener.
187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *
188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * The key to this logic is the use of WAIT_FOR_USER_INPUT and
189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Animation.fillBefore(true). This keeps the alpha animation in its
190b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * beginning state until some key interaction is detected.  On the
191b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * key interaction, the animation start time is reset as appropriate.
192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *
193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * On fade in:
194b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   1.Set and hold the alpha value to 0.0.
195b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   2.Animation is triggered on key down.
196b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   2.Animation is started immediately.
197b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * On fade out:
198b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   1.Set and hold the alpha value to 1.0.
199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   2.Animation is triggered on key up.
200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   2.Animation is FADE_OUT_TIMEOUT after trigger.
201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
202b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        private class DTMFDisplayAnimation extends Handler implements AnimationListener {
203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // events for the fade in and out.
204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final int EVENT_FADE_IN = -1;
205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final int EVENT_FADE_OUT = -2;
206b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // static constants
208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // duration for the fade in animation
209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final int FADE_IN_ANIMATION_TIME = 500;
210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // duration for the fade out animation
211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final int FADE_OUT_ANIMATION_TIME = 1000;
212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Wait time after last user activity to begin fade out.
214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Timeout to match:
215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * {@link com.android.server.PowerManagerService#SHORT_KEYLIGHT_DELAY}
216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final int FADE_OUT_TIMEOUT = 6000;
218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Value indicating we should expect user input.  This is used
221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * to keep animations in the started / initial state until a new
222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * start time is set.
223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final long WAIT_FOR_USER_INPUT = Long.MAX_VALUE;
225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // DTMF display field
227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private View mDTMFDisplay;
228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Fade in / out animations.
230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private AlphaAnimation mFadeIn;
231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private AlphaAnimation mFadeOut;
232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * API implemented for AnimationListener, called on start of animation.
235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            public void onAnimationStart(Animation animation) {}
237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * API implemented for AnimationListener, called on end of animation.
240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * This code just prepares the next animation to be run.
241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            public void onAnimationEnd(Animation animation) {
243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                sendEmptyMessage(animation == mFadeOut ? EVENT_FADE_IN : EVENT_FADE_OUT);
244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * API implemented for AnimationListener, called on repeat of animation.
248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            public void onAnimationRepeat(Animation animation) {}
250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Handle the FADE_IN and FADE_OUT messages
253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            @Override
255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            public void handleMessage(Message msg) {
256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                switch (msg.what) {
257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    case EVENT_FADE_IN:
258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // just initialize to normal fade in.
259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        prepareFadeIn();
260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        break;
261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    case EVENT_FADE_OUT:
262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    default:
263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // set animation to fade out.
264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        mDTMFDisplay.setAnimation(mFadeOut);
265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        break;
266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
267b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
268b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            DTMFDisplayAnimation(EditText display) {
270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDTMFDisplay = display;
271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // create fade in animation
273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeIn = new AlphaAnimation(0.0f, 1.0f);
274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeIn.setDuration(FADE_IN_ANIMATION_TIME);
275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeIn.setAnimationListener(this);
276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeIn.setFillBefore(true);
277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // create fade out animation.
279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut = new AlphaAnimation(1.0f, 0.0f);
280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut.setDuration(FADE_OUT_ANIMATION_TIME);
281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut.setAnimationListener(this);
282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut.setFillBefore(true);
283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Set up dtmf display field for the fade in trigger.
287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            void prepareFadeIn() {
289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDTMFDisplay.setAnimation(mFadeIn);
290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeIn.setStartTime(WAIT_FOR_USER_INPUT);
291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Notify that a key press has occurred, handle the appropriate
295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * animation changes.
296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
297b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            void onKeyDown() {
298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                long currentAnimTime = AnimationUtils.currentAnimationTimeMillis();
299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if ((mDTMFDisplay.getAnimation() == mFadeOut) &&
301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        (mFadeOut.getStartTime() < currentAnimTime)) {
302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // reset the animation if it is running.
303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mFadeOut.reset();
304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else if (mFadeIn.getStartTime() > currentAnimTime){
305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // otherwise start the fade in.
306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mFadeIn.start();
307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Reset the fade out timer.
310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut.setStartTime(WAIT_FOR_USER_INPUT);
311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Notify that a key up has occurred, set the fade out animation
315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * start time accordingly.
316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            void onKeyUp() {
318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut.setStartTime(AnimationUtils.currentAnimationTimeMillis() +
319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        FADE_OUT_TIMEOUT);
320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        private DTMFKeyListener(EditText display) {
324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            super();
325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // setup the display and animation if we're in landscape.
327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (display != null && InCallScreen.ConfigurationHelper.isLandscape()) {
328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDTMFDisplayAnimation = new DTMFDisplayAnimation(display);
329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDTMFDisplayAnimation.prepareFadeIn();
330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Overriden to return correct DTMF-dialable characters.
335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        protected char[] getAcceptedChars(){
338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return DTMF_CHARACTERS;
339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /** special key listener ignores backspace. */
342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean backspace(View view, Editable content, int keyCode,
344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                KeyEvent event) {
345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
346b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
347b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
348b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
349b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Return true if the keyCode is an accepted modifier key for the
350b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * dialer (ALT or SHIFT).
351b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
352b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        private boolean isAcceptableModifierKey(int keyCode) {
353b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (keyCode) {
354b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.KEYCODE_ALT_LEFT:
355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.KEYCODE_ALT_RIGHT:
356b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.KEYCODE_SHIFT_LEFT:
357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.KEYCODE_SHIFT_RIGHT:
358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    return true;
359b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                default:
360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    return false;
361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Overriden so that with each valid button press, we start sending
366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * a dtmf code and play a local dtmf tone.
367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyDown(View view, Editable content,
370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                 int keyCode, KeyEvent event) {
371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if (DBG) log("DTMFKeyListener.onKeyDown, keyCode " + keyCode + ", view " + view);
372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // find the character
374b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            char c = (char) lookup(event, content);
375b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if not a long press, and parent onKeyDown accepts the input
377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (event.getRepeatCount() == 0 && super.onKeyDown(view, content, keyCode, event)) {
378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                boolean keyOK = ok(getAcceptedChars(), c);
380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // show the display on any key down.
382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (mDTMFDisplayAnimation != null && (keyOK || isAcceptableModifierKey(keyCode))) {
383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mDTMFDisplayAnimation.onKeyDown();
384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
385b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if the character is a valid dtmf code, start playing the tone and send the
387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // code.
388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (keyOK) {
389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("DTMFKeyListener reading '" + c + "' from input.");
390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    processDtmf(c);
391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else if (DBG) {
392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    log("DTMFKeyListener rejecting '" + c + "' from input.");
393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
395b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
396b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
397b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
398b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
399b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
400b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Overriden so that with each valid button up, we stop sending
401b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * a dtmf code and the dtmf tone.
402b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
403b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
404b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyUp(View view, Editable content,
405b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                 int keyCode, KeyEvent event) {
406b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if (DBG) log("DTMFKeyListener.onKeyUp, keyCode " + keyCode + ", view " + view);
407b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
408b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            super.onKeyUp(view, content, keyCode, event);
409b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
410b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // find the character
411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            char c = (char) lookup(event, content);
412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
413b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            boolean keyOK = ok(getAcceptedChars(), c);
414b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
415b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // show the display on any key down.
416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (mDTMFDisplayAnimation != null && (keyOK || isAcceptableModifierKey(keyCode))) {
417b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDTMFDisplayAnimation.onKeyUp();
418b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
419b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (keyOK) {
421b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("Stopping the tone for '" + c + "'");
422b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                stopTone();
423b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
424b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
425b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
426b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
427b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
428b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
429b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
430b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Handle individual keydown events when we DO NOT have an Editable handy.
431b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
432b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyDown(KeyEvent event) {
433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            char c = lookup (event);
434b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("recieved keydown for '" + c + "'");
435b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if not a long press, and parent onKeyDown accepts the input
437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (event.getRepeatCount() == 0 && c != 0) {
438b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if the character is a valid dtmf code, start playing the tone and send the
439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // code.
440b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (ok(getAcceptedChars(), c)) {
441b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("DTMFKeyListener reading '" + c + "' from input.");
442b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    processDtmf(c);
443b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    return true;
444b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else if (DBG) {
445b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    log("DTMFKeyListener rejecting '" + c + "' from input.");
446b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
447b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
450b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
452b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Handle individual keyup events.
453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *
454b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * @param event is the event we are trying to stop.  If this is null,
455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * then we just force-stop the last tone without checking if the event
456b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * is an acceptable dialer event.
457b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
458b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyUp(KeyEvent event) {
459b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (event == null) {
460404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville                //the below piece of code sends stopDTMF event unnecessarily even when a null event
461404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville                //is received, hence commenting it.
462404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville                /*if (DBG) log("Stopping the last played tone.");
463404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville                stopTone();*/
464b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
465b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
466b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
467b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            char c = lookup (event);
468b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("recieved keyup for '" + c + "'");
469b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
470b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // TODO: stopTone does not take in character input, we may want to
471b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // consider checking for this ourselves.
472b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (ok(getAcceptedChars(), c)) {
473b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("Stopping the tone for '" + c + "'");
474b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                stopTone();
475b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
476b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
477b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
478b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
479b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
480b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
481b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
482b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Find the Dialer Key mapped to this event.
483b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *
484b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * @return The char value of the input event, otherwise
485b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * 0 if no matching character was found.
486b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
487b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        private char lookup(KeyEvent event) {
488b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // This code is similar to {@link DialerKeyListener#lookup(KeyEvent, Spannable) lookup}
489b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            int meta = event.getMetaState();
490b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            int number = event.getNumber();
491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (!((meta & (KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)) == 0) || (number == 0)) {
493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                int match = event.getMatch(getAcceptedChars(), meta);
494b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                number = (match != 0) ? match : number;
495b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
496b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
497b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return (char) number;
498b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
499b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
500b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
501b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Check to see if the keyEvent is dialable.
502b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
503b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        boolean isKeyEventAcceptable (KeyEvent event) {
504b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return (ok(getAcceptedChars(), lookup(event)));
505b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
506b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
507b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
508b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Overrides the characters used in {@link DialerKeyListener#CHARACTERS}
509b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * These are the valid dtmf characters.
510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
511b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public final char[] DTMF_CHARACTERS = new char[] {
512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '*'
513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        };
514b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
515b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
516b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Our own handler to take care of the messages from the phone state changes
518b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private Handler mHandler = new Handler() {
520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
521b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public void handleMessage(Message msg) {
522b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (msg.what) {
523b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // disconnect action
524b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // make sure to close the dialer on ALL disconnect actions.
525b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case PHONE_DISCONNECT:
526b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("disconnect message recieved, shutting down.");
527b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // unregister since we are closing.
528b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mPhone.unregisterForDisconnect(this);
529b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    closeDialer(false);
530b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
531b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
532b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
533b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    };
534b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
535b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
536b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public DTMFTwelveKeyDialer(InCallScreen parent) {
537b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen = parent;
538b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhone = ((PhoneApp) mInCallScreen.getApplication()).phone;
539b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialerContainer = (SlidingDrawer) mInCallScreen.findViewById(R.id.dialer_container);
540b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
541b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // mDialerContainer is only valid when we're looking at the portrait version of
542b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // dtmf_twelve_key_dialer.
543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDialerContainer != null) {
544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialerContainer.setOnDrawerOpenListener(this);
545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialerContainer.setOnDrawerCloseListener(this);
546b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
547b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Set up the EditText widget that displays DTMF digits in
549b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // landscape mode.  (This widget belongs to the InCallScreen, as
550b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // opposed to mDialpadDigits, which is part of the full dialpad,
551b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // and is used in portrait mode.)
552b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallDigits = mInCallScreen.getDialerDisplay();
553b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
554b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialerKeyListener = new DTMFKeyListener(mInCallDigits);
555b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // If the widget exists, set the behavior correctly.
556b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mInCallDigits != null && InCallScreen.ConfigurationHelper.isLandscape()) {
557b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mInCallDigits.setKeyListener(mDialerKeyListener);
558b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mInCallDigits.setMovementMethod(new DTMFDisplayMovementMethod());
559b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // remove the long-press context menus that support
561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // the edit (copy / paste / select) functions.
562b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mInCallDigits.setLongClickable(false);
563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
565b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
567b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Called when we want to hide the DTMF Display field immediately.
568b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
569b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param shouldHide if true, hide the display (and disable DTMF tones) immediately;
570b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * otherwise, re-enable the display.
571b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
572b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void hideDTMFDisplay(boolean shouldHide) {
573b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        DTMFKeyListener.DTMFDisplayAnimation animation = mDialerKeyListener.mDTMFDisplayAnimation;
574b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
575b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if the animation is in place
576b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (animation != null) {
577b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            View text = animation.mDTMFDisplay;
578b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
579b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // and the display is available
580b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (text != null) {
581b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // hide the display if necessary
582b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                text.setVisibility(shouldHide ? View.GONE : View.VISIBLE);
583b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (shouldHide) {
584b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // null the animation - this makes the display disappear faster
585b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    text.setAnimation(null);
586b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
587b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // otherwise reset the animation to the initial state.
588b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    animation.prepareFadeIn();
589b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Null out our reference to the InCallScreen activity.
596b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This indicates that the InCallScreen activity has been destroyed.
597b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * At the same time, get rid of listeners since we're not going to
598b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * be valid anymore.
599b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
600b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ void clearInCallScreenReference() {
601b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen = null;
602b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialerKeyListener = null;
603b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDialerContainer != null) {
604b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialerContainer.setOnDrawerOpenListener(null);
605b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialerContainer.setOnDrawerCloseListener(null);
606b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
607b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        closeDialer(false);
608b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
609b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
610b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
611b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Dialer code that runs when the dialer is brought up.
612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This includes layout changes, etc, and just prepares the dialer model for use.
613b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
614b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void onDialerOpen() {
615b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("onDialerOpen()...");
616b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
617b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // inflate the view.
618b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialerView = (DTMFTwelveKeyDialerView) mInCallScreen.findViewById(R.id.dtmf_dialer);
619b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialerView.setDialer(this);
620b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
621b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Have the WindowManager filter out cheek touch events
622b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen.getWindow().addFlags(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES);
623b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
624b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhone.registerForDisconnect(mHandler, PHONE_DISCONNECT, null);
625b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
626b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // set to a longer delay while the dialer is up.
627b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        PhoneApp app = PhoneApp.getInstance();
628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        app.updateWakeState();
629b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
630b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // setup the digit display
631b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialpadDigits = (EditText) mDialerView.findViewById(R.id.dtmfDialerField);
632b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialpadDigits.setKeyListener(new DTMFKeyListener(null));
633b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialpadDigits.requestFocus();
634b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
635b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // remove the long-press context menus that support
636b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the edit (copy / paste / select) functions.
637b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialpadDigits.setLongClickable(false);
638b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
639b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Check for the presence of the keypad (portrait mode)
640b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        View view = mDialerView.findViewById(R.id.one);
641b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (view != null) {
642b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("portrait mode setup");
643b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            setupKeypad();
644b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
645b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("landscape mode setup");
646b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Adding hint text to the field to indicate that keyboard
647b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // is needed while in landscape mode.
648b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialpadDigits.setHint(R.string.dialerKeyboardHintText);
649b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
650b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
651b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // setup the local tone generator.
652b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        startDialerSession();
653b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
654b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Give the InCallScreen a chance to do any necessary UI updates.
655b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen.onDialerOpen();
656b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
657b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
658b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
659b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Setup the local tone generator.  Should have corresponding calls to
660b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * {@link onDialerPause}.
661b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
662b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void startDialerSession() {
663b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // see if we need to play local tones.
664b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDTMFToneEnabled = Settings.System.getInt(mInCallScreen.getContentResolver(),
665b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
666b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
667b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // create the tone generator
668b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if the mToneGenerator creation fails, just continue without it.  It is
669b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // a local audio signal, and is not as important as the dtmf tone itself.
670b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDTMFToneEnabled) {
671b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            synchronized (mToneGeneratorLock) {
672b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (mToneGenerator == null) {
673b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    try {
674b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        mToneGenerator = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, 80);
675b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    } catch (RuntimeException e) {
676b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (DBG) log("Exception caught while creating local tone generator: " + e);
677b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        mToneGenerator = null;
678b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
679b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
680b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
681b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
682b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
683b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
684b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
685b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Dialer code that runs when the dialer is closed.
686b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This releases resources acquired when we start the dialer.
687b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
688b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void onDialerClose() {
689b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("onDialerClose()...");
690b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
691b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // reset back to a short delay for the poke lock.
692b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        PhoneApp app = PhoneApp.getInstance();
693b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        app.updateWakeState();
694b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
695b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhone.unregisterForDisconnect(mHandler);
696b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
697b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        stopDialerSession();
698b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
699b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Give the InCallScreen a chance to do any necessary UI updates.
700b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen.onDialerClose();
701b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
702b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
703b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
704b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Tear down the local tone generator, corresponds to calls to
705b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * {@link onDialerResume}
706b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
707b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void stopDialerSession() {
708b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // release the tone generator.
709b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        synchronized (mToneGeneratorLock) {
710b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (mToneGenerator != null) {
711b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mToneGenerator.release();
712b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mToneGenerator = null;
713b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
714b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
715b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
716b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
717b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
718b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * upon completion of the query, update the name field in the status.
719b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
720b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onQueryComplete(int token, Object cookie, CallerInfo ci){
721b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("callerinfo query complete, updating ui.");
722b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
723b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        ((TextView) cookie).setText(PhoneUtils.getCompactNameFromCallerInfo(ci, mInCallScreen));
724b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
725b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
726b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
727b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Called externally (from InCallScreen) to play a DTMF Tone.
728b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
729b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onDialerKeyDown(KeyEvent event) {
730b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("Notifying dtmf key down.");
731b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mDialerKeyListener.onKeyDown(event);
732b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
733b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
734b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
735b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Called externally (from InCallScreen) to cancel the last DTMF Tone played.
736b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
737b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onDialerKeyUp(KeyEvent event) {
738b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("Notifying dtmf key up.");
739b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mDialerKeyListener.onKeyUp(event);
740b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
741b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
742b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
743b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * setup the keys on the dialer activity, using the keymaps.
744b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
745b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void setupKeypad() {
746b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // for each view id listed in the displaymap
747b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        View button;
748b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        for (int viewId : mDisplayMap.keySet()) {
749b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // locate the view
750b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            button = mDialerView.findViewById(viewId);
751b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Setup the listeners for the buttons
752b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            button.setOnTouchListener(this);
753b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            button.setClickable(true);
754b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            button.setOnKeyListener(this);
755b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
756b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
757b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
758b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
759b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * catch the back and call buttons to return to the in call activity.
760b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
761b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
762b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) log("onKeyDown:  keyCode " + keyCode);
763b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (keyCode) {
764b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // finish for these events
765b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case KeyEvent.KEYCODE_BACK:
766b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case KeyEvent.KEYCODE_CALL:
767b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("exit requested");
768b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                closeDialer(true);  // do the "closing" animation
769b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
770b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
771b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mInCallScreen.onKeyDown(keyCode, event);
772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
773b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
774b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
775b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * catch the back and call buttons to return to the in call activity.
776b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
777b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onKeyUp(int keyCode, KeyEvent event) {
778b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) log("onKeyUp:  keyCode " + keyCode);
779b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mInCallScreen.onKeyUp(keyCode, event);
780b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
781b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
782b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
783b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implemented for the TouchListener, process the touch events.
784b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
785b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onTouch(View v, MotionEvent event) {
786b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int viewId = v.getId();
787b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
788b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if the button is recognized
789b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDisplayMap.containsKey(viewId)) {
790b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (event.getAction()) {
791b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case MotionEvent.ACTION_DOWN:
792b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // Append the character mapped to this button, to the display.
793b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // start the tone
794b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    processDtmf(mDisplayMap.get(viewId));
795b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
796b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case MotionEvent.ACTION_UP:
797b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case MotionEvent.ACTION_CANCEL:
798b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // stop the tone on ANY other event, except for MOVE.
799b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    stopTone();
800b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
801b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
802b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // do not return true [handled] here, since we want the
803b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // press / click animation to be handled by the framework.
804b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
805b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
806b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
807b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
808b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
809b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implements View.OnKeyListener for the DTMF buttons.  Enables dialing with trackball/dpad.
810b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
811b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onKey(View v, int keyCode, KeyEvent event) {
812b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) log("onKey:  keyCode " + keyCode + ", view " + v);
813b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
814b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
815b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            int viewId = v.getId();
816b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (mDisplayMap.containsKey(viewId)) {
817b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                switch (event.getAction()) {
818b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.ACTION_DOWN:
819b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (event.getRepeatCount() == 0) {
820b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        processDtmf(mDisplayMap.get(viewId));
821b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
822b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
823b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.ACTION_UP:
824b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    stopTone();
825b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
826b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
827b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // do not return true [handled] here, since we want the
828b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // press / click animation to be handled by the framework.
829b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
830b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
831b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
832b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
833b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
834b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
835b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @return true if the dialer is currently opened (i.e. expanded).
836b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
837b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean isOpened() {
838b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mDialerContainer != null && mDialerContainer.isOpened();
839b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
840b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
841b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
842b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Forces the dialer into the "open" state.
843b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Does nothing if the dialer is already open.
844b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
845b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param animate if true, open the dialer with an animation.
846b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
847b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void openDialer(boolean animate) {
848b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDialerContainer != null && !mDialerContainer.isOpened()) {
849b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (animate) {
850b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDialerContainer.animateToggle();
851b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
852b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDialerContainer.toggle();
853b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
854b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
855b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
856b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
857b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
858b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Forces the dialer into the "closed" state.
859b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Does nothing if the dialer is already closed.
860b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
861b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param animate if true, close the dialer with an animation.
862b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
863b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void closeDialer(boolean animate) {
864b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDialerContainer != null && mDialerContainer.isOpened()) {
865b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (animate) {
866b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDialerContainer.animateToggle();
867b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
868b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDialerContainer.toggle();
869b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
870b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
871b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
872b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
873b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
874b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implemented for the SlidingDrawer open listener, prepare the dialer.
875b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
876b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onDrawerOpened() {
877b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        onDialerOpen();
878b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
879b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
880b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
881b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implemented for the SlidingDrawer close listener, release the dialer.
882b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
883b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onDrawerClosed() {
884b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        onDialerClose();
885b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
886b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
887b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
888b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Processes the specified digit as a DTMF key, by playing the
889b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * appropriate DTMF tone, and appending the digit to the EditText
890b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * field that displays the DTMF digits sent so far.
891b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
892b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private final void processDtmf(char c) {
893b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if it is a valid key, then update the display and send the dtmf tone.
894b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (PhoneNumberUtils.is12Key(c)) {
895b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("updating display and sending dtmf tone for '" + c + "'");
896b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
897b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (mDialpadDigits != null) {
898b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDialpadDigits.getText().append(c);
899b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
900b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
901b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Note we *don't* need to manually append this digit to the
902b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // landscape-mode EditText field (mInCallDigits), since it
903b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // gets key events directly and automatically appends whetever
904b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // the user types.
905b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
906b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Play the tone if it exists.
907b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (mToneMap.containsKey(c)) {
908b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // begin tone playback.
909b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                startTone(c);
910b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
911b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else if (DBG) {
912b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            log("ignoring dtmf request for '" + c + "'");
913b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
914b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
9154472ce7a7e8568b4bb66098c4e4a2e71099167acDavid Brown        // Any DTMF keypress counts as explicit "user activity".
9164472ce7a7e8568b4bb66098c4e4a2e71099167acDavid Brown        PhoneApp.getInstance().pokeUserActivity();
917b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
918b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
919b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
920b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Clears out the display of "DTMF digits typed so far" that's kept in
921b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * either mDialpadDigits or mInCallDigits (depending on whether we're
922b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * in portrait or landscape mode.)
923b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
924b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * The InCallScreen is responsible for calling this method any time a
925b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * new call becomes active (or, more simply, any time a call ends).
926b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This is how we make sure that the "history" of DTMF digits you type
927b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * doesn't persist from one call to the next.
928b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
929b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * TODO: it might be more elegent if the dialpad itself could remember
930b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * the call that we're associated with, and clear the digits if the
931b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * "current call" has changed since last time.  (This would require
932b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * some unique identifier that's different for each call.  We can't
933b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * just use the foreground Call object, since that's a singleton that
934b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * lasts the whole life of the phone process.  Instead, maybe look at
935b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * the Connection object that comes back from getEarliestConnection()?
936b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Or getEarliestConnectTime()?)
937b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
938b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Or to be even fancier, we could keep a mapping of *multiple*
939b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * "active calls" to DTMF strings.  That way you could have two lines
940b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * in use and swap calls multiple times, and we'd still remember the
941b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * digits for each call.  (But that's such an obscure use case that
942b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * it's probably not worth the extra complexity.)
943b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
944b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void clearDigits() {
945b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("clearDigits()...");
946b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
947b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDialpadDigits != null) {
948b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialpadDigits.setText("");
949b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
950b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mInCallDigits != null) {
951b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mInCallDigits.setText("");
952b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
953b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
954b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
955b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
956b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Starts playing a DTMF tone.  Also begins the local tone playback,
957b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * if enabled.
958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param tone a tone code from {@link ToneGenerator}
960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void startTone(char tone) {
962b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("startTone()...");
963b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        PhoneApp.getInstance().phone.startDtmf(tone);
964b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if local tone playback is enabled, start it.
966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDTMFToneEnabled) {
967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            synchronized (mToneGeneratorLock) {
968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (mToneGenerator == null) {
969b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("startTone: mToneGenerator == null, tone: " + tone);
970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
971b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("starting local tone " + tone);
972b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mToneGenerator.startTone(mToneMap.get(tone));
973b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
974b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
975b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
978b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Stops playing the current DTMF tone.
980b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
981b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * The ToneStopper class (similar to that in {@link TwelveKeyDialer#mToneStopper})
982b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * has been removed in favor of synchronous start / stop calls since tone duration
983b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * is now a function of the input.
984b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
985b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void stopTone() {
986b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("stopTone()...");
987b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        PhoneApp.getInstance().phone.stopDtmf();
988b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
989b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if local tone playback is enabled, stop it.
990b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("trying to stop local tone...");
991b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDTMFToneEnabled) {
992b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            synchronized (mToneGeneratorLock) {
993b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (mToneGenerator == null) {
994b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("stopTone: mToneGenerator == null");
995b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
996b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("stopping local tone.");
997b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mToneGenerator.stopTone();
998b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
999b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
1000b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1001b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1002b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1003b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1004b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Check to see if the keyEvent is dialable.
1005b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1006b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    boolean isKeyEventAcceptable (KeyEvent event) {
1007b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return (mDialerKeyListener != null && mDialerKeyListener.isKeyEventAcceptable(event));
1008b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1009b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1010b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1011b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * static logging method
1012b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1013b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static void log(String msg) {
1014b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Log.d(LOG_TAG, msg);
1015b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1016b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project}
1017