DTMFTwelveKeyDialer.java revision 921814d9a5a90d4826d781dc70986ef82a786ad1
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;
47d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Savilleimport java.util.LinkedList;
48d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Savilleimport java.util.Queue;
49d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
50b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
51b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/**
52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Dialer class that encapsulates the DTMF twelve key behaviour.
53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This model backs up the UI behaviour in DTMFTwelveKeyDialerView.java.
54b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */
55b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class DTMFTwelveKeyDialer implements
56b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        CallerInfoAsyncQuery.OnQueryCompleteListener,
57b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        SlidingDrawer.OnDrawerOpenListener,
58b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        SlidingDrawer.OnDrawerCloseListener,
59b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        View.OnTouchListener,
60b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        View.OnKeyListener {
61b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final String LOG_TAG = "DTMFTwelveKeyDialer";
62796c70c99bc39295bf685061056f06ab8949c742David Brown    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
63b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
64b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // events
65b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final int PHONE_DISCONNECT = 100;
66d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    private static final int DTMF_SEND_CNF = 101;
67d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    private static final int STOP_DTMF_TONE = 102;
68d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
69d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
70b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
71bd6ef6be5bbece60afee7f1ef0a6bba732298dacDavid Brown    private Phone mPhone;
72b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ToneGenerator mToneGenerator;
73b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private Object mToneGeneratorLock = new Object();
74b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
75b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // indicate if we want to enable the DTMF tone playback.
76b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private boolean mDTMFToneEnabled;
77b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
78d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    // DTMF tone type
79d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    private int mDTMFToneType;
80d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
81d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    // indicate if the confirmation from TelephonyFW is pending.
82d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    private boolean mDTMFBurstCnfPending = false;
83d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
84d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    // Queue to queue the short dtmf characters.
85d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    private Queue<Character> mDTMFQueue = new LinkedList<Character>();
86d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
87d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    //  Short Dtmf tone duration
88d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    private static final int DTMF_DURATION_MS = 120;
89d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
90d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
91b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** Hash Map to map a character to a tone*/
92b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final HashMap<Character, Integer> mToneMap =
93b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        new HashMap<Character, Integer>();
94b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** Hash Map to map a view id to a character*/
95b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final HashMap<Integer, Character> mDisplayMap =
96b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        new HashMap<Integer, Character>();
97b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** Set up the static maps*/
98b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static {
99b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Map the key characters to tones
100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('1', ToneGenerator.TONE_DTMF_1);
101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('2', ToneGenerator.TONE_DTMF_2);
102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('3', ToneGenerator.TONE_DTMF_3);
103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('4', ToneGenerator.TONE_DTMF_4);
104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('5', ToneGenerator.TONE_DTMF_5);
105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('6', ToneGenerator.TONE_DTMF_6);
106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('7', ToneGenerator.TONE_DTMF_7);
107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('8', ToneGenerator.TONE_DTMF_8);
108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('9', ToneGenerator.TONE_DTMF_9);
109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('0', ToneGenerator.TONE_DTMF_0);
110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('#', ToneGenerator.TONE_DTMF_P);
111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mToneMap.put('*', ToneGenerator.TONE_DTMF_S);
112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Map the buttons to the display characters
114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.one, '1');
115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.two, '2');
116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.three, '3');
117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.four, '4');
118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.five, '5');
119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.six, '6');
120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.seven, '7');
121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.eight, '8');
122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.nine, '9');
123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.zero, '0');
124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.pound, '#');
125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDisplayMap.put(R.id.star, '*');
126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // EditText field used to display the DTMF digits sent so far.
129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // - In portrait mode, we use the EditText that comes from
130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    //   the full dialpad:
131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private EditText mDialpadDigits;
132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // - In landscape mode, we use a different EditText that's
133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    //   built into the InCallScreen:
134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private EditText mInCallDigits;
135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // (Only one of these will be visible at any given point.)
136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // InCallScreen reference.
138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private InCallScreen mInCallScreen;
139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
140b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // SlidingDrawer reference.
141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private SlidingDrawer mDialerContainer;
142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // view reference
144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private DTMFTwelveKeyDialerView mDialerView;
145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // key listner reference, may or may not be attached to a view.
147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private DTMFKeyListener mDialerKeyListener;
148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Create an input method just so that the textview can display the cursor.
151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * There is no selecting / positioning on the dialer field, only number input.
152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
153bd6ef6be5bbece60afee7f1ef0a6bba732298dacDavid Brown    private static class DTMFDisplayMovementMethod implements MovementMethod {
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 onKeyDown(TextView widget, Spannable buffer, int keyCode, KeyEvent event) {
157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Return false since we are NOT consuming the input.*/
161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode, KeyEvent event) {
162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Return false since we are NOT consuming the input.*/
166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {
167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Return false since we are NOT consuming the input.*/
171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onTrackballEvent(TextView widget, Spannable buffer, MotionEvent event) {
172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Return false since we are NOT consuming the input.*/
176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
178b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public void initialize(TextView widget, Spannable text) {
181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public void onTakeFocus(TextView view, Spannable text, int dir) {
184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
186b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**Disallow arbitrary selection.*/
187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean canSelectArbitrarily() {
188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
190b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
191b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Our own key listener, specialized for dealing with DTMF codes.
194b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   1. Ignore the backspace since it is irrelevant.
195b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   2. Allow ONLY valid DTMF characters to generate a tone and be
196b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *      sent as a DTMF code.
197b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   3. All other remaining characters are handled by the superclass.
198b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private class DTMFKeyListener extends DialerKeyListener {
200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        private DTMFDisplayAnimation mDTMFDisplayAnimation;
202b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Class that controls the fade in/out of the DTMF dialer field.
205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Logic is tied into the keystroke events handled by the
206b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * DTMFKeyListener.
207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *
208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * The key to this logic is the use of WAIT_FOR_USER_INPUT and
209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Animation.fillBefore(true). This keeps the alpha animation in its
210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * beginning state until some key interaction is detected.  On the
211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * key interaction, the animation start time is reset as appropriate.
212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *
213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * On fade in:
214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   1.Set and hold the alpha value to 0.0.
215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   2.Animation is triggered on key down.
216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   2.Animation is started immediately.
217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * On fade out:
218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   1.Set and hold the alpha value to 1.0.
219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   2.Animation is triggered on key up.
220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *   2.Animation is FADE_OUT_TIMEOUT after trigger.
221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        private class DTMFDisplayAnimation extends Handler implements AnimationListener {
223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // events for the fade in and out.
224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final int EVENT_FADE_IN = -1;
225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final int EVENT_FADE_OUT = -2;
226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // static constants
228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // duration for the fade in animation
229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final int FADE_IN_ANIMATION_TIME = 500;
230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // duration for the fade out animation
231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final int FADE_OUT_ANIMATION_TIME = 1000;
232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Wait time after last user activity to begin fade out.
234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Timeout to match:
235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * {@link com.android.server.PowerManagerService#SHORT_KEYLIGHT_DELAY}
236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final int FADE_OUT_TIMEOUT = 6000;
238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Value indicating we should expect user input.  This is used
241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * to keep animations in the started / initial state until a new
242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * start time is set.
243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private static final long WAIT_FOR_USER_INPUT = Long.MAX_VALUE;
245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // DTMF display field
247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private View mDTMFDisplay;
248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Fade in / out animations.
250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private AlphaAnimation mFadeIn;
251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            private AlphaAnimation mFadeOut;
252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * API implemented for AnimationListener, called on start of animation.
255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            public void onAnimationStart(Animation animation) {}
257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * API implemented for AnimationListener, called on end of animation.
260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * This code just prepares the next animation to be run.
261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            public void onAnimationEnd(Animation animation) {
263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                sendEmptyMessage(animation == mFadeOut ? EVENT_FADE_IN : EVENT_FADE_OUT);
264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
267b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * API implemented for AnimationListener, called on repeat of animation.
268b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            public void onAnimationRepeat(Animation animation) {}
270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Handle the FADE_IN and FADE_OUT messages
273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            @Override
275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            public void handleMessage(Message msg) {
276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                switch (msg.what) {
277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    case EVENT_FADE_IN:
278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // just initialize to normal fade in.
279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        prepareFadeIn();
280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        break;
281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    case EVENT_FADE_OUT:
282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    default:
283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // set animation to fade out.
284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        mDTMFDisplay.setAnimation(mFadeOut);
285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        break;
286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            DTMFDisplayAnimation(EditText display) {
290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDTMFDisplay = display;
291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // create fade in animation
293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeIn = new AlphaAnimation(0.0f, 1.0f);
294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeIn.setDuration(FADE_IN_ANIMATION_TIME);
295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeIn.setAnimationListener(this);
296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeIn.setFillBefore(true);
297b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // create fade out animation.
299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut = new AlphaAnimation(1.0f, 0.0f);
300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut.setDuration(FADE_OUT_ANIMATION_TIME);
301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut.setAnimationListener(this);
302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut.setFillBefore(true);
303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Set up dtmf display field for the fade in trigger.
307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            void prepareFadeIn() {
309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDTMFDisplay.setAnimation(mFadeIn);
310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeIn.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 press has occurred, handle the appropriate
315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * animation changes.
316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            void onKeyDown() {
318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                long currentAnimTime = AnimationUtils.currentAnimationTimeMillis();
319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if ((mDTMFDisplay.getAnimation() == mFadeOut) &&
321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        (mFadeOut.getStartTime() < currentAnimTime)) {
322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // reset the animation if it is running.
323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mFadeOut.reset();
324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else if (mFadeIn.getStartTime() > currentAnimTime){
325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // otherwise start the fade in.
326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mFadeIn.start();
327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Reset the fade out timer.
330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut.setStartTime(WAIT_FOR_USER_INPUT);
331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            /**
334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * Notify that a key up has occurred, set the fade out animation
335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             * start time accordingly.
336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project             */
337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            void onKeyUp() {
338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mFadeOut.setStartTime(AnimationUtils.currentAnimationTimeMillis() +
339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        FADE_OUT_TIMEOUT);
340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        private DTMFKeyListener(EditText display) {
344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            super();
345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
346b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // setup the display and animation if we're in landscape.
347b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (display != null && InCallScreen.ConfigurationHelper.isLandscape()) {
348b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDTMFDisplayAnimation = new DTMFDisplayAnimation(display);
349b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDTMFDisplayAnimation.prepareFadeIn();
350b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
351b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
352b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
353b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
354b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Overriden to return correct DTMF-dialable characters.
355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
356b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        protected char[] getAcceptedChars(){
358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return DTMF_CHARACTERS;
359b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /** special key listener ignores backspace. */
362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean backspace(View view, Editable content, int keyCode,
364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                KeyEvent event) {
365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Return true if the keyCode is an accepted modifier key for the
370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * dialer (ALT or SHIFT).
371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        private boolean isAcceptableModifierKey(int keyCode) {
373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (keyCode) {
374b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.KEYCODE_ALT_LEFT:
375b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.KEYCODE_ALT_RIGHT:
376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.KEYCODE_SHIFT_LEFT:
377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.KEYCODE_SHIFT_RIGHT:
378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    return true;
379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                default:
380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    return false;
381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
385b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Overriden so that with each valid button press, we start sending
386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * a dtmf code and play a local dtmf tone.
387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyDown(View view, Editable content,
390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                 int keyCode, KeyEvent event) {
391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if (DBG) log("DTMFKeyListener.onKeyDown, keyCode " + keyCode + ", view " + view);
392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // find the character
394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            char c = (char) lookup(event, content);
395b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
396b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if not a long press, and parent onKeyDown accepts the input
397b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (event.getRepeatCount() == 0 && super.onKeyDown(view, content, keyCode, event)) {
398b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
399b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                boolean keyOK = ok(getAcceptedChars(), c);
400b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
401b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // show the display on any key down.
402b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (mDTMFDisplayAnimation != null && (keyOK || isAcceptableModifierKey(keyCode))) {
403b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mDTMFDisplayAnimation.onKeyDown();
404b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
405b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
406b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if the character is a valid dtmf code, start playing the tone and send the
407b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // code.
408b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (keyOK) {
409b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("DTMFKeyListener reading '" + c + "' from input.");
410b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    processDtmf(c);
411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else if (DBG) {
412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    log("DTMFKeyListener rejecting '" + c + "' from input.");
413b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
414b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
415b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
417b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
418b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
419b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Overriden so that with each valid button up, we stop sending
421b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * a dtmf code and the dtmf tone.
422b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
423b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
424b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyUp(View view, Editable content,
425b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                 int keyCode, KeyEvent event) {
426b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if (DBG) log("DTMFKeyListener.onKeyUp, keyCode " + keyCode + ", view " + view);
427b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
428b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            super.onKeyUp(view, content, keyCode, event);
429b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
430b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // find the character
431b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            char c = (char) lookup(event, content);
432b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            boolean keyOK = ok(getAcceptedChars(), c);
434b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
435b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // show the display on any key down.
436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (mDTMFDisplayAnimation != null && (keyOK || isAcceptableModifierKey(keyCode))) {
437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDTMFDisplayAnimation.onKeyUp();
438b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
440b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (keyOK) {
441b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("Stopping the tone for '" + c + "'");
442b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                stopTone();
443b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
444b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
445b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
446b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
447b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
450b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Handle individual keydown events when we DO NOT have an Editable handy.
451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
452b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyDown(KeyEvent event) {
453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            char c = lookup (event);
454b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("recieved keydown for '" + c + "'");
455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
456b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if not a long press, and parent onKeyDown accepts the input
457b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (event.getRepeatCount() == 0 && c != 0) {
458b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if the character is a valid dtmf code, start playing the tone and send the
459b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // code.
460b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (ok(getAcceptedChars(), c)) {
461b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("DTMFKeyListener reading '" + c + "' from input.");
462b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    processDtmf(c);
463b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    return true;
464b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else if (DBG) {
465b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    log("DTMFKeyListener rejecting '" + c + "' from input.");
466b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
467b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
468b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
469b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
470b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
471b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
472b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Handle individual keyup events.
473b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *
474b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * @param event is the event we are trying to stop.  If this is null,
475b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * then we just force-stop the last tone without checking if the event
476b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * is an acceptable dialer event.
477b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
478b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public boolean onKeyUp(KeyEvent event) {
479b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (event == null) {
480404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville                //the below piece of code sends stopDTMF event unnecessarily even when a null event
481404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville                //is received, hence commenting it.
482404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville                /*if (DBG) log("Stopping the last played tone.");
483404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville                stopTone();*/
484b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
485b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
486b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
487b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            char c = lookup (event);
488b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("recieved keyup for '" + c + "'");
489b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
490b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // TODO: stopTone does not take in character input, we may want to
491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // consider checking for this ourselves.
492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (ok(getAcceptedChars(), c)) {
493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("Stopping the tone for '" + c + "'");
494b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                stopTone();
495b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
496b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
497b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
498b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
499b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
500b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
501b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
502b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Find the Dialer Key mapped to this event.
503b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         *
504b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * @return The char value of the input event, otherwise
505b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * 0 if no matching character was found.
506b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
507b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        private char lookup(KeyEvent event) {
508b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // This code is similar to {@link DialerKeyListener#lookup(KeyEvent, Spannable) lookup}
509b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            int meta = event.getMetaState();
510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            int number = event.getNumber();
511b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (!((meta & (KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)) == 0) || (number == 0)) {
513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                int match = event.getMatch(getAcceptedChars(), meta);
514b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                number = (match != 0) ? match : number;
515b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
516b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return (char) number;
518b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
521b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Check to see if the keyEvent is dialable.
522b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
523b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        boolean isKeyEventAcceptable (KeyEvent event) {
524b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return (ok(getAcceptedChars(), lookup(event)));
525b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
526b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
527b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /**
528b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * Overrides the characters used in {@link DialerKeyListener#CHARACTERS}
529b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         * These are the valid dtmf characters.
530b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project         */
531b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public final char[] DTMF_CHARACTERS = new char[] {
532b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '*'
533b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        };
534b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
535b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
536b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
537b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Our own handler to take care of the messages from the phone state changes
538b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
539b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private Handler mHandler = new Handler() {
540b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
541b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public void handleMessage(Message msg) {
542b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (msg.what) {
543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // disconnect action
544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // make sure to close the dialer on ALL disconnect actions.
545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case PHONE_DISCONNECT:
546b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("disconnect message recieved, shutting down.");
547b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // unregister since we are closing.
548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mPhone.unregisterForDisconnect(this);
549b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    closeDialer(false);
550b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
551d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                case DTMF_SEND_CNF:
552d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    if (DBG) log("dtmf confirmation received from FW.");
553d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    // handle burst dtmf confirmation
554d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    handleBurstDtmfConfirmation();
555d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    break;
556d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                case STOP_DTMF_TONE:
557d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    if (DBG) log("stop-dtmf-tone received.");
558d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    stopToneCdma();
559d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    break;
560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
562b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    };
563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
565b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public DTMFTwelveKeyDialer(InCallScreen parent) {
566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen = parent;
567b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhone = ((PhoneApp) mInCallScreen.getApplication()).phone;
568b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialerContainer = (SlidingDrawer) mInCallScreen.findViewById(R.id.dialer_container);
569b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
570b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // mDialerContainer is only valid when we're looking at the portrait version of
571b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // dtmf_twelve_key_dialer.
572b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDialerContainer != null) {
573b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialerContainer.setOnDrawerOpenListener(this);
574b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialerContainer.setOnDrawerCloseListener(this);
575b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
576b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
577b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Set up the EditText widget that displays DTMF digits in
578b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // landscape mode.  (This widget belongs to the InCallScreen, as
579b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // opposed to mDialpadDigits, which is part of the full dialpad,
580b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // and is used in portrait mode.)
581b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallDigits = mInCallScreen.getDialerDisplay();
582b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
583b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialerKeyListener = new DTMFKeyListener(mInCallDigits);
584b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // If the widget exists, set the behavior correctly.
585b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mInCallDigits != null && InCallScreen.ConfigurationHelper.isLandscape()) {
586b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mInCallDigits.setKeyListener(mDialerKeyListener);
587b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mInCallDigits.setMovementMethod(new DTMFDisplayMovementMethod());
588b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
589b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // remove the long-press context menus that support
590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // the edit (copy / paste / select) functions.
591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mInCallDigits.setLongClickable(false);
592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
596b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Called when we want to hide the DTMF Display field immediately.
597b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
598b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param shouldHide if true, hide the display (and disable DTMF tones) immediately;
599b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * otherwise, re-enable the display.
600b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
601b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void hideDTMFDisplay(boolean shouldHide) {
602b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        DTMFKeyListener.DTMFDisplayAnimation animation = mDialerKeyListener.mDTMFDisplayAnimation;
603b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
604b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if the animation is in place
605b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (animation != null) {
606b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            View text = animation.mDTMFDisplay;
607b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
608b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // and the display is available
609b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (text != null) {
610b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // hide the display if necessary
611b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                text.setVisibility(shouldHide ? View.GONE : View.VISIBLE);
612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (shouldHide) {
613b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // null the animation - this makes the display disappear faster
614b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    text.setAnimation(null);
615b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
616b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // otherwise reset the animation to the initial state.
617b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    animation.prepareFadeIn();
618b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
619b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
620b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
621b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
622b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
623b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
624b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Null out our reference to the InCallScreen activity.
625b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This indicates that the InCallScreen activity has been destroyed.
626b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * At the same time, get rid of listeners since we're not going to
627b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * be valid anymore.
628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
629b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ void clearInCallScreenReference() {
630b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen = null;
631b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialerKeyListener = null;
632b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDialerContainer != null) {
633b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialerContainer.setOnDrawerOpenListener(null);
634b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialerContainer.setOnDrawerCloseListener(null);
635b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
636d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (mPhone.getPhoneName().equals("CDMA")) {
637d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            mHandler.removeMessages(STOP_DTMF_TONE);
638d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            mHandler.removeMessages(DTMF_SEND_CNF);
639d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            synchronized (mDTMFQueue) {
640d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                mDTMFBurstCnfPending = false;
641d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                mDTMFQueue.clear();
642d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            }
643d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        }
644b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        closeDialer(false);
645b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
646b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
647b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
648b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Dialer code that runs when the dialer is brought up.
649b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This includes layout changes, etc, and just prepares the dialer model for use.
650b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
651b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void onDialerOpen() {
652b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("onDialerOpen()...");
653b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
654b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // inflate the view.
655b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialerView = (DTMFTwelveKeyDialerView) mInCallScreen.findViewById(R.id.dtmf_dialer);
656b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialerView.setDialer(this);
657b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
658b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Have the WindowManager filter out cheek touch events
659b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen.getWindow().addFlags(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES);
660b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
661b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhone.registerForDisconnect(mHandler, PHONE_DISCONNECT, null);
662b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
663b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // set to a longer delay while the dialer is up.
664b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        PhoneApp app = PhoneApp.getInstance();
665b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        app.updateWakeState();
666b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
667b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // setup the digit display
668b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialpadDigits = (EditText) mDialerView.findViewById(R.id.dtmfDialerField);
669b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialpadDigits.setKeyListener(new DTMFKeyListener(null));
670b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialpadDigits.requestFocus();
671b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
672b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // remove the long-press context menus that support
673b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the edit (copy / paste / select) functions.
674b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mDialpadDigits.setLongClickable(false);
675b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
676b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Check for the presence of the keypad (portrait mode)
677b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        View view = mDialerView.findViewById(R.id.one);
678b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (view != null) {
679b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("portrait mode setup");
680b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            setupKeypad();
681b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
682b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("landscape mode setup");
683b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Adding hint text to the field to indicate that keyboard
684b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // is needed while in landscape mode.
685b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialpadDigits.setHint(R.string.dialerKeyboardHintText);
686b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
687b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
688b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Give the InCallScreen a chance to do any necessary UI updates.
689b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen.onDialerOpen();
690b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
691b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
692b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
6931066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * Allocates some resources we keep around during a "dialer session".
6941066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     *
6951066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * (Currently, a "dialer session" just means any situation where we
6961066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * might need to play local DTMF tones, which means that we need to
6971066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * keep a ToneGenerator instance around.  A ToneGenerator instance
6981066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * keeps an AudioTrack resource busy in AudioFlinger, so we don't want
6991066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * to keep it around forever.)
7001066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     *
7011066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * Call {@link stopDialerSession} to release the dialer session
7021066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * resources.
703b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
704b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void startDialerSession() {
705b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // see if we need to play local tones.
706921814d9a5a90d4826d781dc70986ef82a786ad1Paul Berman        if (mPhone.getContext().getResources().getBoolean(R.bool.allow_local_dtmf_tones)) {
707921814d9a5a90d4826d781dc70986ef82a786ad1Paul Berman            mDTMFToneEnabled = Settings.System.getInt(mInCallScreen.getContentResolver(),
708921814d9a5a90d4826d781dc70986ef82a786ad1Paul Berman                    Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
709921814d9a5a90d4826d781dc70986ef82a786ad1Paul Berman        } else {
710921814d9a5a90d4826d781dc70986ef82a786ad1Paul Berman            mDTMFToneEnabled = false;
711921814d9a5a90d4826d781dc70986ef82a786ad1Paul Berman        }
712b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
713b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // create the tone generator
714b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if the mToneGenerator creation fails, just continue without it.  It is
715b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // a local audio signal, and is not as important as the dtmf tone itself.
716b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDTMFToneEnabled) {
717b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            synchronized (mToneGeneratorLock) {
718b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (mToneGenerator == null) {
719b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    try {
720aa23e1c3c758bad23d8b6709147cc1ff7cd1e43cEric Laurent                        mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF, 80);
721b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    } catch (RuntimeException e) {
722b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (DBG) log("Exception caught while creating local tone generator: " + e);
723b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        mToneGenerator = null;
724b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
725b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
726b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
727b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
728b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
729b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
730b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
731b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Dialer code that runs when the dialer is closed.
732b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This releases resources acquired when we start the dialer.
733b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
734b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void onDialerClose() {
735b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("onDialerClose()...");
736b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
737b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // reset back to a short delay for the poke lock.
738b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        PhoneApp app = PhoneApp.getInstance();
739b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        app.updateWakeState();
740b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
741b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhone.unregisterForDisconnect(mHandler);
742b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
743b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Give the InCallScreen a chance to do any necessary UI updates.
744b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen.onDialerClose();
745b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
746b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
747b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
7481066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * Releases resources we keep around during a "dialer session"
7491066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * (see {@link startDialerSession}).
7501066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     *
7511066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * It's safe to call this even without a corresponding
7521066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown     * startDialerSession call.
753b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
754b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void stopDialerSession() {
755b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // release the tone generator.
756b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        synchronized (mToneGeneratorLock) {
757b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (mToneGenerator != null) {
758b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mToneGenerator.release();
759b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mToneGenerator = null;
760b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
761b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
762b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
763b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
764b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
765b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * upon completion of the query, update the name field in the status.
766b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
767b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onQueryComplete(int token, Object cookie, CallerInfo ci){
768b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("callerinfo query complete, updating ui.");
769b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
770b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        ((TextView) cookie).setText(PhoneUtils.getCompactNameFromCallerInfo(ci, mInCallScreen));
771b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
773b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
774b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Called externally (from InCallScreen) to play a DTMF Tone.
775b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
776b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onDialerKeyDown(KeyEvent event) {
777b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("Notifying dtmf key down.");
778b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mDialerKeyListener.onKeyDown(event);
779b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
780b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
781b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
782b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Called externally (from InCallScreen) to cancel the last DTMF Tone played.
783b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
784b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onDialerKeyUp(KeyEvent event) {
785b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("Notifying dtmf key up.");
786b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mDialerKeyListener.onKeyUp(event);
787b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
788b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
789b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
790b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * setup the keys on the dialer activity, using the keymaps.
791b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
792b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void setupKeypad() {
793b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // for each view id listed in the displaymap
794b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        View button;
795b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        for (int viewId : mDisplayMap.keySet()) {
796b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // locate the view
797b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            button = mDialerView.findViewById(viewId);
798b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Setup the listeners for the buttons
799b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            button.setOnTouchListener(this);
800b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            button.setClickable(true);
801b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            button.setOnKeyListener(this);
802b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
803b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
804b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
805b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
806b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * catch the back and call buttons to return to the in call activity.
807b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
808b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
809b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) log("onKeyDown:  keyCode " + keyCode);
810b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (keyCode) {
811b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // finish for these events
812b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case KeyEvent.KEYCODE_BACK:
813b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case KeyEvent.KEYCODE_CALL:
814b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("exit requested");
815b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                closeDialer(true);  // do the "closing" animation
816b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
817b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
818b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mInCallScreen.onKeyDown(keyCode, event);
819b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
820b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
821b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
822b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * catch the back and call buttons to return to the in call activity.
823b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
824b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onKeyUp(int keyCode, KeyEvent event) {
825b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) log("onKeyUp:  keyCode " + keyCode);
826b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mInCallScreen.onKeyUp(keyCode, event);
827b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
828b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
829b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
830b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implemented for the TouchListener, process the touch events.
831b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
832b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onTouch(View v, MotionEvent event) {
833b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int viewId = v.getId();
834b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
835b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if the button is recognized
836b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDisplayMap.containsKey(viewId)) {
837b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (event.getAction()) {
838b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case MotionEvent.ACTION_DOWN:
839b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // Append the character mapped to this button, to the display.
840b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // start the tone
841b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    processDtmf(mDisplayMap.get(viewId));
842b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
843b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case MotionEvent.ACTION_UP:
844b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case MotionEvent.ACTION_CANCEL:
845b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // stop the tone on ANY other event, except for MOVE.
846b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    stopTone();
847b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
848b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
849b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // do not return true [handled] here, since we want the
850b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // press / click animation to be handled by the framework.
851b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
852b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
853b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
854b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
855b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
856b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implements View.OnKeyListener for the DTMF buttons.  Enables dialing with trackball/dpad.
857b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
858b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean onKey(View v, int keyCode, KeyEvent event) {
859b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) log("onKey:  keyCode " + keyCode + ", view " + v);
860b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
861b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
862b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            int viewId = v.getId();
863b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (mDisplayMap.containsKey(viewId)) {
864b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                switch (event.getAction()) {
865b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.ACTION_DOWN:
866b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (event.getRepeatCount() == 0) {
867b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        processDtmf(mDisplayMap.get(viewId));
868b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
869b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
870b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case KeyEvent.ACTION_UP:
871b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    stopTone();
872b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
873b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
874b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // do not return true [handled] here, since we want the
875b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // press / click animation to be handled by the framework.
876b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
877b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
878b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
879b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
880b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
881b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
882b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @return true if the dialer is currently opened (i.e. expanded).
883b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
884b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean isOpened() {
885b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mDialerContainer != null && mDialerContainer.isOpened();
886b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
887b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
888b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
889b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Forces the dialer into the "open" state.
890b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Does nothing if the dialer is already open.
891b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
892b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param animate if true, open the dialer with an animation.
893b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
894b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void openDialer(boolean animate) {
895b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDialerContainer != null && !mDialerContainer.isOpened()) {
896b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (animate) {
897b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDialerContainer.animateToggle();
898b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
899b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDialerContainer.toggle();
900b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
901b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
902b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
903b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
904b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
905b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Forces the dialer into the "closed" state.
906b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Does nothing if the dialer is already closed.
907b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
908b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param animate if true, close the dialer with an animation.
909b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
910b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void closeDialer(boolean animate) {
911b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDialerContainer != null && mDialerContainer.isOpened()) {
912b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (animate) {
913b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDialerContainer.animateToggle();
914b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
915b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDialerContainer.toggle();
916b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
917b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
918b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
919b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
920b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
921b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implemented for the SlidingDrawer open listener, prepare the dialer.
922b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
923b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onDrawerOpened() {
924b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        onDialerOpen();
925b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
926b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
927b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
928b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implemented for the SlidingDrawer close listener, release the dialer.
929b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
930b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onDrawerClosed() {
931b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        onDialerClose();
932b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
933b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
934b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
935b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Processes the specified digit as a DTMF key, by playing the
936b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * appropriate DTMF tone, and appending the digit to the EditText
937b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * field that displays the DTMF digits sent so far.
938b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
939b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private final void processDtmf(char c) {
940b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if it is a valid key, then update the display and send the dtmf tone.
941b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (PhoneNumberUtils.is12Key(c)) {
942b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("updating display and sending dtmf tone for '" + c + "'");
943b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
944b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (mDialpadDigits != null) {
945b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mDialpadDigits.getText().append(c);
946b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
947b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
948b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Note we *don't* need to manually append this digit to the
949b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // landscape-mode EditText field (mInCallDigits), since it
950b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // gets key events directly and automatically appends whetever
951b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // the user types.
952b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
953b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Play the tone if it exists.
954b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (mToneMap.containsKey(c)) {
955b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // begin tone playback.
956b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                startTone(c);
957b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else if (DBG) {
959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            log("ignoring dtmf request for '" + c + "'");
960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
9624472ce7a7e8568b4bb66098c4e4a2e71099167acDavid Brown        // Any DTMF keypress counts as explicit "user activity".
9634472ce7a7e8568b4bb66098c4e4a2e71099167acDavid Brown        PhoneApp.getInstance().pokeUserActivity();
964b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Clears out the display of "DTMF digits typed so far" that's kept in
968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * either mDialpadDigits or mInCallDigits (depending on whether we're
969b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * in portrait or landscape mode.)
970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
971b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * The InCallScreen is responsible for calling this method any time a
972b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * new call becomes active (or, more simply, any time a call ends).
973b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This is how we make sure that the "history" of DTMF digits you type
974b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * doesn't persist from one call to the next.
975b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * TODO: it might be more elegent if the dialpad itself could remember
977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * the call that we're associated with, and clear the digits if the
978b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * "current call" has changed since last time.  (This would require
979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * some unique identifier that's different for each call.  We can't
980b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * just use the foreground Call object, since that's a singleton that
981b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * lasts the whole life of the phone process.  Instead, maybe look at
982b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * the Connection object that comes back from getEarliestConnection()?
983b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Or getEarliestConnectTime()?)
984b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
985b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Or to be even fancier, we could keep a mapping of *multiple*
986b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * "active calls" to DTMF strings.  That way you could have two lines
987b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * in use and swap calls multiple times, and we'd still remember the
988b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * digits for each call.  (But that's such an obscure use case that
989b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * it's probably not worth the extra complexity.)
990b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
991b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void clearDigits() {
992b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("clearDigits()...");
993b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
994b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDialpadDigits != null) {
995b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mDialpadDigits.setText("");
996b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
997b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mInCallDigits != null) {
998b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mInCallDigits.setText("");
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     * Starts playing a DTMF tone.  Also begins the local tone playback,
1004b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * if enabled.
1005d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * The access of this function is package rather than private
1006d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * since this is being referred from InCallScreen.
1007d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * InCallScreen calls this function to utilize the DTMF ToneGenerator properties
1008d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * defined here.
1009b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param tone a tone code from {@link ToneGenerator}
1010b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1011d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    /* package */ void startDtmfTone(char tone) {
1012d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (DBG) log("startDtmfTone()...");
1013d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        mPhone.startDtmf(tone);
1014b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1015b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if local tone playback is enabled, start it.
1016b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDTMFToneEnabled) {
1017b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            synchronized (mToneGeneratorLock) {
1018b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (mToneGenerator == null) {
1019d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    if (DBG) log("startDtmfTone: mToneGenerator == null, tone: " + tone);
1020b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
1021b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("starting local tone " + tone);
1022b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mToneGenerator.startTone(mToneMap.get(tone));
1023b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1024b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
1025b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1026b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1027b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1028b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1029b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Stops playing the current DTMF tone.
1030b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
1031b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * The ToneStopper class (similar to that in {@link TwelveKeyDialer#mToneStopper})
1032b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * has been removed in favor of synchronous start / stop calls since tone duration
1033b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * is now a function of the input.
1034d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * The acess of this function is package rather than private
1035d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * since this is being referred from InCallScreen.
1036d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * InCallScreen calls this function to utilize the DTMF ToneGenerator properties
1037d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * defined here.
1038b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1039d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    /* package */ void stopDtmfTone() {
1040d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (DBG) log("stopDtmfTone()...");
1041d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        mPhone.stopDtmf();
1042b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1043b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if local tone playback is enabled, stop it.
1044b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("trying to stop local tone...");
1045b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mDTMFToneEnabled) {
1046b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            synchronized (mToneGeneratorLock) {
1047b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (mToneGenerator == null) {
1048d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    if (DBG) log("stopDtmfTone: mToneGenerator == null");
1049b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
1050b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("stopping local tone.");
1051b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mToneGenerator.stopTone();
1052b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1053b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
1054b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1055b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1056b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1057b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1058b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Check to see if the keyEvent is dialable.
1059b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1060b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    boolean isKeyEventAcceptable (KeyEvent event) {
1061b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return (mDialerKeyListener != null && mDialerKeyListener.isKeyEventAcceptable(event));
1062b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1063b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1064b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1065b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * static logging method
1066b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1067b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static void log(String msg) {
1068b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Log.d(LOG_TAG, msg);
1069b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1070d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
1071d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    /**
1072d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * Plays the local tone based the phone type.
1073d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     */
1074d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    private void startTone(char c) {
1075d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (mPhone.getPhoneName().equals("GSM")) {
1076d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            startDtmfTone(c);
1077d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        } else {
1078d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            startToneCdma(c);
1079d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        }
1080d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    }
1081d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
1082d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    /**
1083d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * Stops the local tone based on the phone type.
1084d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     */
1085d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    private void stopTone() {
1086d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (mPhone.getPhoneName().equals("GSM")) {
1087d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            stopDtmfTone();
1088d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        } else {
1089d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            // Cdma case we do stopTone only for Long DTMF Setting
1090d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            if (mDTMFToneType == CallFeaturesSetting.DTMF_TONE_TYPE_LONG) {
1091d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                stopToneCdma();
1092d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            }
1093d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        }
1094d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    }
1095d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
1096d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    /**
1097d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * Plays tone when the DTMF setting is normal(Short).
1098d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     */
1099d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    void startToneCdma(char tone) {
1100d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        // Read the settings as it may be changed by the user during the call
1101d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        mDTMFToneType = Settings.System.getInt(mInCallScreen.getContentResolver(),
1102d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                Settings.System.DTMF_TONE_TYPE_WHEN_DIALING,
1103cd0189299f484dcbd51400b994daf585923e9e8dDavid Krause                CallFeaturesSetting.DTMF_TONE_TYPE_NORMAL);
1104d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        // For Short DTMF we need to play the local tone for fixed duration
1105d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (mDTMFToneType == CallFeaturesSetting.DTMF_TONE_TYPE_NORMAL) {
1106d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            sendShortDtmfToNetwork (tone);
1107d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        } else {
1108d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            // Pass as a char to be sent to network
1109d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            Log.i(LOG_TAG, "send long dtmf for " + tone);
1110d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            mPhone.startDtmf(tone);
1111d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        }
1112d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
111399e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting        startLocalToneCdma(tone);
111499e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting    }
111599e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting
111699e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting    /**
111799e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting     * Plays local tone for CDMA.
111899e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting     */
111999e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting    void startLocalToneCdma(char tone) {
1120d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        // if local tone playback is enabled, start it.
1121d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (mDTMFToneEnabled) {
1122d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            synchronized (mToneGeneratorLock) {
1123d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                if (mToneGenerator == null) {
1124d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    if (DBG) log("startToneCdma: mToneGenerator == null, tone: " + tone);
1125d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                } else {
1126d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    if (DBG) log("starting local tone " + tone);
1127d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
11280b78bb2224ddc1991ba2b9f31087010109b90b14Paul Berman                    // Start the new tone.
1129d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    mToneGenerator.startTone(mToneMap.get(tone));
113080fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu
113180fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu                    // Stopped pending and Started new STOP_DTMF_TONE timer.
113280fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu                    if (mDTMFToneType == CallFeaturesSetting.DTMF_TONE_TYPE_NORMAL) {
113380fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu                        mHandler.removeMessages(STOP_DTMF_TONE);
113480fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu                        mHandler.sendEmptyMessageDelayed(STOP_DTMF_TONE,DTMF_DURATION_MS);
113580fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu                    }
113680fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu                }
1137d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            }
1138d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        }
1139d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    }
1140d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
1141d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    /**
1142d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * Sends the dtmf character over the network for short DTMF settings
114380fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu     * When the characters are entered in quick succession,
114480fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu     * the characters are queued before sending over the network.
1145d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     */
1146d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    private void sendShortDtmfToNetwork(char dtmfDigit) {
1147d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        synchronized (mDTMFQueue) {
1148d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            if (mDTMFBurstCnfPending == true) {
1149d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                // Insert the dtmf char to the queue
1150d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                mDTMFQueue.add(new Character(dtmfDigit));
1151d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            } else {
1152d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                String dtmfStr = Character.toString(dtmfDigit);
1153d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                Log.i(LOG_TAG,"dtmfsent = " + dtmfStr);
115456a783bb160a377a5edb6617ca5bfbe9927ef7dejsh                mPhone.sendBurstDtmf(dtmfStr, 0, 0, mHandler.obtainMessage(DTMF_SEND_CNF));
1155d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                // Set flag to indicate wait for Telephony confirmation.
1156d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                mDTMFBurstCnfPending = true;
1157d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            }
1158d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        }
1159d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    }
1160d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
1161d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    /**
1162d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * Stops the dtmf from being sent over the network for Long DTMF case and stops local DTMF key feedback tone.
1163d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     */
1164d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    private void stopToneCdma() {
1165d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (DBG) log("stopping remote tone.");
1166d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
1167d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (mDTMFToneType == CallFeaturesSetting.DTMF_TONE_TYPE_LONG) {
1168d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            mPhone.stopDtmf();
1169d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        }
1170d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
117199e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting        stopLocalToneCdma();
117299e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting    }
117399e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting
117499e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting    /**
117599e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting     * Stops the local dtmf tone.
117699e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting     */
117799e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting    void stopLocalToneCdma() {
1178d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        // if local tone playback is enabled, stop it.
1179d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (DBG) log("trying to stop local tone...");
1180d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (mDTMFToneEnabled) {
1181d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            synchronized (mToneGeneratorLock) {
1182d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                if (mToneGenerator == null) {
1183d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    if (DBG) log("stopToneCdma: mToneGenerator == null");
1184d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                } else {
1185d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    if (DBG) log("stopping local tone.");
1186d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                    mToneGenerator.stopTone();
1187d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                }
1188d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            }
1189d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        }
1190d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    }
1191d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville
1192d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    /**
1193d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     * Handles Burst Dtmf Confirmation from the Framework.
1194d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville     */
1195d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    void handleBurstDtmfConfirmation() {
1196d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        Character dtmfChar = null;
1197d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        synchronized(mDTMFQueue) {
1198d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            mDTMFBurstCnfPending = false;
1199d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            if(!mDTMFQueue.isEmpty()) {
1200d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                dtmfChar = mDTMFQueue.remove();
1201d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville                Log.i(LOG_TAG, "The dtmf character removed from queue" + dtmfChar);
1202d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            }
1203d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        }
1204d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        if (dtmfChar != null) {
1205d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville            sendShortDtmfToNetwork(dtmfChar);
1206d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville        }
1207d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville    }
1208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project}
1209