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.widget.EditText; 34b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.TextView; 35b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 36fa08be2879b66dc61a8e0b5a85dfdd7ef942570bHung-ying Tyanimport com.android.internal.telephony.CallManager; 37b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.Phone; 38b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 39b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport java.util.HashMap; 40d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Savilleimport java.util.LinkedList; 41d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Savilleimport java.util.Queue; 42d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 43b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 44b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/** 45b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Dialer class that encapsulates the DTMF twelve key behaviour. 46b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This model backs up the UI behaviour in DTMFTwelveKeyDialerView.java. 47b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 484ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brownpublic class DTMFTwelveKeyDialer implements View.OnTouchListener, View.OnKeyListener { 49b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final String LOG_TAG = "DTMFTwelveKeyDialer"; 501e8a3579f8e49fd1f1a078d6be6864a6a8bac306David Brown private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2); 51b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // events 53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int PHONE_DISCONNECT = 100; 54d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville private static final int DTMF_SEND_CNF = 101; 55d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 56fa08be2879b66dc61a8e0b5a85dfdd7ef942570bHung-ying Tyan private CallManager mCM; 57b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private ToneGenerator mToneGenerator; 58b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private Object mToneGeneratorLock = new Object(); 59b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 6051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // indicate if we want to enable the local tone playback. 6151eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon private boolean mLocalToneEnabled; 62b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 6351eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // indicates that we are using automatically shortened DTMF tones 6451eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon boolean mShortTone; 65d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 66d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville // indicate if the confirmation from TelephonyFW is pending. 67d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville private boolean mDTMFBurstCnfPending = false; 68d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 69d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville // Queue to queue the short dtmf characters. 70d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville private Queue<Character> mDTMFQueue = new LinkedList<Character>(); 71d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 72d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville // Short Dtmf tone duration 73d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville private static final int DTMF_DURATION_MS = 120; 74d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 75d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 76b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** Hash Map to map a character to a tone*/ 77b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final HashMap<Character, Integer> mToneMap = 78b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project new HashMap<Character, Integer>(); 79b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** Hash Map to map a view id to a character*/ 80b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final HashMap<Integer, Character> mDisplayMap = 81b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project new HashMap<Integer, Character>(); 82b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** Set up the static maps*/ 83b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project static { 84b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Map the key characters to tones 85b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('1', ToneGenerator.TONE_DTMF_1); 86b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('2', ToneGenerator.TONE_DTMF_2); 87b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('3', ToneGenerator.TONE_DTMF_3); 88b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('4', ToneGenerator.TONE_DTMF_4); 89b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('5', ToneGenerator.TONE_DTMF_5); 90b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('6', ToneGenerator.TONE_DTMF_6); 91b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('7', ToneGenerator.TONE_DTMF_7); 92b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('8', ToneGenerator.TONE_DTMF_8); 93b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('9', ToneGenerator.TONE_DTMF_9); 94b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('0', ToneGenerator.TONE_DTMF_0); 95b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('#', ToneGenerator.TONE_DTMF_P); 96b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneMap.put('*', ToneGenerator.TONE_DTMF_S); 97b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 98b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Map the buttons to the display characters 99b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.one, '1'); 100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.two, '2'); 101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.three, '3'); 102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.four, '4'); 103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.five, '5'); 104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.six, '6'); 105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.seven, '7'); 106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.eight, '8'); 107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.nine, '9'); 108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.zero, '0'); 109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.pound, '#'); 110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDisplayMap.put(R.id.star, '*'); 111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // EditText field used to display the DTMF digits sent so far. 114dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // Note this is null in some modes (like during the CDMA OTA call, 115dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // where there's no onscreen "digits" display.) 116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private EditText mDialpadDigits; 117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // InCallScreen reference. 119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private InCallScreen mInCallScreen; 120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1215aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown // The DTMFTwelveKeyDialerView we use to display the dialpad. 122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private DTMFTwelveKeyDialerView mDialerView; 123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 124dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // KeyListener used with the "dialpad digits" EditText widget. 125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private DTMFKeyListener mDialerKeyListener; 126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Our own key listener, specialized for dealing with DTMF codes. 129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1. Ignore the backspace since it is irrelevant. 130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 2. Allow ONLY valid DTMF characters to generate a tone and be 131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * sent as a DTMF code. 132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 3. All other remaining characters are handled by the superclass. 133dfa83d531cdb88513f09e913424b7a16628b37d3David Brown * 134dfa83d531cdb88513f09e913424b7a16628b37d3David Brown * This code is purely here to handle events from the hardware keyboard 135dfa83d531cdb88513f09e913424b7a16628b37d3David Brown * while the DTMF dialpad is up. 136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private class DTMFKeyListener extends DialerKeyListener { 138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 139dfa83d531cdb88513f09e913424b7a16628b37d3David Brown private DTMFKeyListener() { 140b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super(); 141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Overriden to return correct DTMF-dialable characters. 145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project protected char[] getAcceptedChars(){ 148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return DTMF_CHARACTERS; 149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** special key listener ignores backspace. */ 152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean backspace(View view, Editable content, int keyCode, 154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project KeyEvent event) { 155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Return true if the keyCode is an accepted modifier key for the 160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * dialer (ALT or SHIFT). 161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private boolean isAcceptableModifierKey(int keyCode) { 163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (keyCode) { 164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_ALT_LEFT: 165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_ALT_RIGHT: 166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_SHIFT_LEFT: 167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_SHIFT_RIGHT: 168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Overriden so that with each valid button press, we start sending 176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * a dtmf code and play a local dtmf tone. 177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 178b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onKeyDown(View view, Editable content, 180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int keyCode, KeyEvent event) { 181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("DTMFKeyListener.onKeyDown, keyCode " + keyCode + ", view " + view); 182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // find the character 184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project char c = (char) lookup(event, content); 185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 186b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if not a long press, and parent onKeyDown accepts the input 187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (event.getRepeatCount() == 0 && super.onKeyDown(view, content, keyCode, event)) { 188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean keyOK = ok(getAcceptedChars(), c); 190b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 191b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the character is a valid dtmf code, start playing the tone and send the 192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // code. 193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (keyOK) { 194b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("DTMFKeyListener reading '" + c + "' from input."); 195b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project processDtmf(c); 196b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (DBG) { 197b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project log("DTMFKeyListener rejecting '" + c + "' from input."); 198b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 202b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Overriden so that with each valid button up, we stop sending 206b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * a dtmf code and the dtmf tone. 207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onKeyUp(View view, Editable content, 210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int keyCode, KeyEvent event) { 211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("DTMFKeyListener.onKeyUp, keyCode " + keyCode + ", view " + view); 212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super.onKeyUp(view, content, keyCode, event); 214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // find the character 216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project char c = (char) lookup(event, content); 217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean keyOK = ok(getAcceptedChars(), c); 219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (keyOK) { 221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("Stopping the tone for '" + c + "'"); 222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project stopTone(); 223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Handle individual keydown events when we DO NOT have an Editable handy. 231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onKeyDown(KeyEvent event) { 233dfa83d531cdb88513f09e913424b7a16628b37d3David Brown char c = lookup(event); 234dfa83d531cdb88513f09e913424b7a16628b37d3David Brown if (DBG) log("DTMFKeyListener.onKeyDown: event '" + c + "'"); 235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if not a long press, and parent onKeyDown accepts the input 237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (event.getRepeatCount() == 0 && c != 0) { 238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the character is a valid dtmf code, start playing the tone and send the 239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // code. 240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (ok(getAcceptedChars(), c)) { 241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("DTMFKeyListener reading '" + c + "' from input."); 242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project processDtmf(c); 243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (DBG) { 245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project log("DTMFKeyListener rejecting '" + c + "' from input."); 246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Handle individual keyup events. 253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @param event is the event we are trying to stop. If this is null, 255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * then we just force-stop the last tone without checking if the event 256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * is an acceptable dialer event. 257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onKeyUp(KeyEvent event) { 259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (event == null) { 260404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville //the below piece of code sends stopDTMF event unnecessarily even when a null event 261404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville //is received, hence commenting it. 262404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville /*if (DBG) log("Stopping the last played tone."); 263404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville stopTone();*/ 264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 267dfa83d531cdb88513f09e913424b7a16628b37d3David Brown char c = lookup(event); 268dfa83d531cdb88513f09e913424b7a16628b37d3David Brown if (DBG) log("DTMFKeyListener.onKeyUp: event '" + c + "'"); 269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: stopTone does not take in character input, we may want to 271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // consider checking for this ourselves. 272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (ok(getAcceptedChars(), c)) { 273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("Stopping the tone for '" + c + "'"); 274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project stopTone(); 275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Find the Dialer Key mapped to this event. 283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @return The char value of the input event, otherwise 285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 0 if no matching character was found. 286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private char lookup(KeyEvent event) { 288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // This code is similar to {@link DialerKeyListener#lookup(KeyEvent, Spannable) lookup} 289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int meta = event.getMetaState(); 290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int number = event.getNumber(); 291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!((meta & (KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)) == 0) || (number == 0)) { 293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int match = event.getMatch(getAcceptedChars(), meta); 294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project number = (match != 0) ? match : number; 295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 297b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return (char) number; 298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Check to see if the keyEvent is dialable. 302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean isKeyEventAcceptable (KeyEvent event) { 304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return (ok(getAcceptedChars(), lookup(event))); 305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Overrides the characters used in {@link DialerKeyListener#CHARACTERS} 309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * These are the valid dtmf characters. 310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public final char[] DTMF_CHARACTERS = new char[] { 312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '*' 313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }; 314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Our own handler to take care of the messages from the phone state changes 318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private Handler mHandler = new Handler() { 320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void handleMessage(Message msg) { 322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (msg.what) { 323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // disconnect action 324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // make sure to close the dialer on ALL disconnect actions. 325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case PHONE_DISCONNECT: 326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("disconnect message recieved, shutting down."); 327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // unregister since we are closing. 328fa08be2879b66dc61a8e0b5a85dfdd7ef942570bHung-ying Tyan mCM.unregisterForDisconnect(this); 329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project closeDialer(false); 330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 331d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville case DTMF_SEND_CNF: 332d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville if (DBG) log("dtmf confirmation received from FW."); 333d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville // handle burst dtmf confirmation 334d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville handleBurstDtmfConfirmation(); 335d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville break; 336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }; 339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 340dfa83d531cdb88513f09e913424b7a16628b37d3David Brown 341dfa83d531cdb88513f09e913424b7a16628b37d3David Brown /** 342dfa83d531cdb88513f09e913424b7a16628b37d3David Brown * DTMFTwelveKeyDialer constructor. 343dfa83d531cdb88513f09e913424b7a16628b37d3David Brown * 344dfa83d531cdb88513f09e913424b7a16628b37d3David Brown * @param parent the InCallScreen instance that owns us. 345dfa83d531cdb88513f09e913424b7a16628b37d3David Brown * @param dialerView the DTMFTwelveKeyDialerView we should use to display the dialpad. 346dfa83d531cdb88513f09e913424b7a16628b37d3David Brown */ 347dfa83d531cdb88513f09e913424b7a16628b37d3David Brown public DTMFTwelveKeyDialer(InCallScreen parent, 3484ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown DTMFTwelveKeyDialerView dialerView) { 3492f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown if (DBG) log("DTMFTwelveKeyDialer constructor... this = " + this); 3508df5c508da2c836b841ee24120fa7c5cc92df387David Brown 351b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mInCallScreen = parent; 352fa08be2879b66dc61a8e0b5a85dfdd7ef942570bHung-ying Tyan mCM = PhoneApp.getInstance().mCM; 353dfa83d531cdb88513f09e913424b7a16628b37d3David Brown 354dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // The passed-in DTMFTwelveKeyDialerView *should* always be 355dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // non-null, now that the in-call UI uses only portrait mode. 356dfa83d531cdb88513f09e913424b7a16628b37d3David Brown if (dialerView == null) { 357dfa83d531cdb88513f09e913424b7a16628b37d3David Brown Log.e(LOG_TAG, "DTMFTwelveKeyDialer: null dialerView!", new IllegalStateException()); 358dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // ...continue as best we can, although things will 359dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // be pretty broken without the mDialerView UI elements! 360dfa83d531cdb88513f09e913424b7a16628b37d3David Brown } 361dfa83d531cdb88513f09e913424b7a16628b37d3David Brown mDialerView = dialerView; 3628df5c508da2c836b841ee24120fa7c5cc92df387David Brown if (DBG) log("- Got passed-in mDialerView: " + mDialerView); 3638df5c508da2c836b841ee24120fa7c5cc92df387David Brown 364dfa83d531cdb88513f09e913424b7a16628b37d3David Brown if (mDialerView != null) { 365c8f1376d0d710a27390feb46ab810c2eae2c45f8Peng Zhu mDialerView.setDialer(this); 366dfa83d531cdb88513f09e913424b7a16628b37d3David Brown 367dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // In the normal in-call DTMF dialpad, mDialpadDigits is an 368dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // EditText used to display the digits the user has typed so 369dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // far. But some other modes (like the OTA call) have no 370dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // "digits" display at all, in which case mDialpadDigits will 371dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // be null. 372dfa83d531cdb88513f09e913424b7a16628b37d3David Brown mDialpadDigits = (EditText) mDialerView.findViewById(R.id.dtmfDialerField); 373dfa83d531cdb88513f09e913424b7a16628b37d3David Brown if (mDialpadDigits != null) { 374dfa83d531cdb88513f09e913424b7a16628b37d3David Brown mDialerKeyListener = new DTMFKeyListener(); 375dfa83d531cdb88513f09e913424b7a16628b37d3David Brown mDialpadDigits.setKeyListener(mDialerKeyListener); 376dfa83d531cdb88513f09e913424b7a16628b37d3David Brown 377dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // remove the long-press context menus that support 378dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // the edit (copy / paste / select) functions. 379dfa83d531cdb88513f09e913424b7a16628b37d3David Brown mDialpadDigits.setLongClickable(false); 380dfa83d531cdb88513f09e913424b7a16628b37d3David Brown } 381dfa83d531cdb88513f09e913424b7a16628b37d3David Brown 382dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // Hook up touch / key listeners for the buttons in the onscreen 383dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // keypad. 384dfa83d531cdb88513f09e913424b7a16628b37d3David Brown setupKeypad(mDialerView); 385c8f1376d0d710a27390feb46ab810c2eae2c45f8Peng Zhu } 386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Null out our reference to the InCallScreen activity. 390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This indicates that the InCallScreen activity has been destroyed. 391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * At the same time, get rid of listeners since we're not going to 392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * be valid anymore. 393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ void clearInCallScreenReference() { 395dfa83d531cdb88513f09e913424b7a16628b37d3David Brown if (DBG) log("clearInCallScreenReference()..."); 396b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mInCallScreen = null; 397b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDialerKeyListener = null; 39851eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mHandler.removeMessages(DTMF_SEND_CNF); 39951eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon synchronized (mDTMFQueue) { 40051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mDTMFBurstCnfPending = false; 40151eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mDTMFQueue.clear(); 402d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 403b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project closeDialer(false); 404b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 405b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 406b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 407b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Dialer code that runs when the dialer is brought up. 408b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This includes layout changes, etc, and just prepares the dialer model for use. 409b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 410b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onDialerOpen() { 411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("onDialerOpen()..."); 412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 413dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // Any time the dialer is open, listen for "disconnect" events (so 414dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // we can close ourself.) 415fa08be2879b66dc61a8e0b5a85dfdd7ef942570bHung-ying Tyan mCM.registerForDisconnect(mHandler, PHONE_DISCONNECT, null); 416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 417dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // On some devices the screen timeout is set to a special value 418dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // while the dialpad is up. 419986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller PhoneApp.getInstance().updateWakeState(); 420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 421dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // Give the InCallScreen a chance to do any necessary UI updates. 422dfa83d531cdb88513f09e913424b7a16628b37d3David Brown mInCallScreen.onDialerOpen(); 423b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 424b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 425b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 4261066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * Allocates some resources we keep around during a "dialer session". 4271066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * 4281066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * (Currently, a "dialer session" just means any situation where we 4291066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * might need to play local DTMF tones, which means that we need to 4301066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * keep a ToneGenerator instance around. A ToneGenerator instance 4311066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * keeps an AudioTrack resource busy in AudioFlinger, so we don't want 4321066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * to keep it around forever.) 4331066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * 4341066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * Call {@link stopDialerSession} to release the dialer session 4351066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * resources. 436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void startDialerSession() { 4382f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown if (DBG) log("startDialerSession()... this = " + this); 4392f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown 440b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // see if we need to play local tones. 441fa08be2879b66dc61a8e0b5a85dfdd7ef942570bHung-ying Tyan if (PhoneApp.getInstance().getResources().getBoolean(R.bool.allow_local_dtmf_tones)) { 44251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mLocalToneEnabled = Settings.System.getInt(mInCallScreen.getContentResolver(), 443921814d9a5a90d4826d781dc70986ef82a786ad1Paul Berman Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1; 444921814d9a5a90d4826d781dc70986ef82a786ad1Paul Berman } else { 44551eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mLocalToneEnabled = false; 446921814d9a5a90d4826d781dc70986ef82a786ad1Paul Berman } 44751eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (DBG) log("- startDialerSession: mLocalToneEnabled = " + mLocalToneEnabled); 448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // create the tone generator 450b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the mToneGenerator creation fails, just continue without it. It is 451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // a local audio signal, and is not as important as the dtmf tone itself. 45251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (mLocalToneEnabled) { 453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project synchronized (mToneGeneratorLock) { 454b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mToneGenerator == null) { 455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project try { 456aa23e1c3c758bad23d8b6709147cc1ff7cd1e43cEric Laurent mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF, 80); 457b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } catch (RuntimeException e) { 458b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("Exception caught while creating local tone generator: " + e); 459b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneGenerator = null; 460b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 461b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 462b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 463b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 464b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 465b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 466b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 467b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Dialer code that runs when the dialer is closed. 468b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This releases resources acquired when we start the dialer. 469b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 470b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onDialerClose() { 471b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("onDialerClose()..."); 472b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 473b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // reset back to a short delay for the poke lock. 474b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneApp app = PhoneApp.getInstance(); 475b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project app.updateWakeState(); 476b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 477fa08be2879b66dc61a8e0b5a85dfdd7ef942570bHung-ying Tyan mCM.unregisterForDisconnect(mHandler); 478b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 479b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Give the InCallScreen a chance to do any necessary UI updates. 480a8de03f8104ac78874a50ebccf14d1d50b34b016David Brown if (mInCallScreen != null) { 481a8de03f8104ac78874a50ebccf14d1d50b34b016David Brown mInCallScreen.onDialerClose(); 482a8de03f8104ac78874a50ebccf14d1d50b34b016David Brown } 483b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 484b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 485b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 4861066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * Releases resources we keep around during a "dialer session" 4871066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * (see {@link startDialerSession}). 4881066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * 4891066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * It's safe to call this even without a corresponding 4901066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown * startDialerSession call. 491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void stopDialerSession() { 493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // release the tone generator. 494b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project synchronized (mToneGeneratorLock) { 495b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mToneGenerator != null) { 496b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneGenerator.release(); 497b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneGenerator = null; 498b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 499b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 500b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 501b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 502b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 503b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Called externally (from InCallScreen) to play a DTMF Tone. 504b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 505b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onDialerKeyDown(KeyEvent event) { 506b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("Notifying dtmf key down."); 507b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return mDialerKeyListener.onKeyDown(event); 508b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 509b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 511b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Called externally (from InCallScreen) to cancel the last DTMF Tone played. 512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onDialerKeyUp(KeyEvent event) { 514b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("Notifying dtmf key up."); 515b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return mDialerKeyListener.onKeyUp(event); 516b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 518b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * setup the keys on the dialer activity, using the keymaps. 520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 521dfa83d531cdb88513f09e913424b7a16628b37d3David Brown private void setupKeypad(DTMFTwelveKeyDialerView dialerView) { 522b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // for each view id listed in the displaymap 523b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project View button; 524b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project for (int viewId : mDisplayMap.keySet()) { 525b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // locate the view 526dfa83d531cdb88513f09e913424b7a16628b37d3David Brown button = dialerView.findViewById(viewId); 527b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Setup the listeners for the buttons 528b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project button.setOnTouchListener(this); 529b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project button.setClickable(true); 530b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project button.setOnKeyListener(this); 531b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 532b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 533b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 534b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 535b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * catch the back and call buttons to return to the in call activity. 536b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 537b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 538b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("onKeyDown: keyCode " + keyCode); 539b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (keyCode) { 540b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // finish for these events 541b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_BACK: 542b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_CALL: 543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("exit requested"); 544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project closeDialer(true); // do the "closing" animation 545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 546b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 547b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return mInCallScreen.onKeyDown(keyCode, event); 548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 549b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 550b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 551b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * catch the back and call buttons to return to the in call activity. 552b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 553b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 554b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("onKeyUp: keyCode " + keyCode); 555b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return mInCallScreen.onKeyUp(keyCode, event); 556b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 557b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 558b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 559b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Implemented for the TouchListener, process the touch events. 560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onTouch(View v, MotionEvent event) { 562b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int viewId = v.getId(); 563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the button is recognized 565b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mDisplayMap.containsKey(viewId)) { 566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (event.getAction()) { 567b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case MotionEvent.ACTION_DOWN: 568b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Append the character mapped to this button, to the display. 569b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // start the tone 570b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project processDtmf(mDisplayMap.get(viewId)); 571b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 572b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case MotionEvent.ACTION_UP: 573b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case MotionEvent.ACTION_CANCEL: 574b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // stop the tone on ANY other event, except for MOVE. 575b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project stopTone(); 576b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 577b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 578b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // do not return true [handled] here, since we want the 579b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // press / click animation to be handled by the framework. 580b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 581b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 582b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 583b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 584b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 585b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Implements View.OnKeyListener for the DTMF buttons. Enables dialing with trackball/dpad. 586b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 587b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onKey(View v, int keyCode, KeyEvent event) { 588b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("onKey: keyCode " + keyCode + ", view " + v); 589b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int viewId = v.getId(); 592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mDisplayMap.containsKey(viewId)) { 593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (event.getAction()) { 594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.ACTION_DOWN: 595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (event.getRepeatCount() == 0) { 596b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project processDtmf(mDisplayMap.get(viewId)); 597b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 598b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 599b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.ACTION_UP: 600b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project stopTone(); 601b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 602b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 603b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // do not return true [handled] here, since we want the 604b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // press / click animation to be handled by the framework. 605b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 606b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 607b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 608b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 609b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 610b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 6115aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown * @return true if the dialer is currently visible onscreen. 612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 6135aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown // TODO: clean up naming inconsistency of "opened" vs. "visible". 6145aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown // This should be called isVisible(), and open/closeDialer() should 6155aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown // be "show" and "hide". 616b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean isOpened() { 6174ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Return whether or not the dialer view is visible. 6185cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // (Note that if we're in the middle of a fade-out animation, that 6195cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // also counts as "not visible" even though mDialerView itself is 6205cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // technically still VISIBLE.) 6215cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown return ((mDialerView.getVisibility() == View.VISIBLE) 6225cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown && !CallCard.Fade.isFadingOut(mDialerView)); 623b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 624b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 625b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 626b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Forces the dialer into the "open" state. 627b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Does nothing if the dialer is already open. 628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 629b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @param animate if true, open the dialer with an animation. 630b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 631b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void openDialer(boolean animate) { 6325aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown if (DBG) log("openDialer()..."); 6335aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown 6345aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown if (!isOpened()) { 6354ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Make the dialer view visible. 6365cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if (animate) { 6375cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown CallCard.Fade.show(mDialerView); 6385cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } else { 6395cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown mDialerView.setVisibility(View.VISIBLE); 6405cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } 6414ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown onDialerOpen(); 642b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 643b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 644b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 645b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 646b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Forces the dialer into the "closed" state. 647b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Does nothing if the dialer is already closed. 648b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 649b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @param animate if true, close the dialer with an animation. 650b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 651b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void closeDialer(boolean animate) { 6525aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown if (DBG) log("closeDialer()..."); 6535aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown 6545aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown if (isOpened()) { 6554ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Hide the dialer view. 6565cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if (animate) { 6575cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown CallCard.Fade.hide(mDialerView, View.GONE); 6585cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } else { 6595cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown mDialerView.setVisibility(View.GONE); 6605cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } 6614ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown onDialerClose(); 662b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 663b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 664b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 665b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 666b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Processes the specified digit as a DTMF key, by playing the 667b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * appropriate DTMF tone, and appending the digit to the EditText 668b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * field that displays the DTMF digits sent so far. 669b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 670b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private final void processDtmf(char c) { 671b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if it is a valid key, then update the display and send the dtmf tone. 672b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (PhoneNumberUtils.is12Key(c)) { 673b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updating display and sending dtmf tone for '" + c + "'"); 674b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 675dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // Append this key to the "digits" widget. 676b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mDialpadDigits != null) { 677dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // TODO: maybe *don't* manually append this digit if 678dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // mDialpadDigits is focused and this key came from the HW 679dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // keyboard, since in that case the EditText field will 680dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // get the key event directly and automatically appends 681dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // whetever the user types. 682dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // (Or, a cleaner fix would be to just make mDialpadDigits 683dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // *not* handle HW key presses. That seems to be more 684dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // complicated than just setting focusable="false" on it, 685dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // though.) 686b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDialpadDigits.getText().append(c); 687b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 688b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 689b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Play the tone if it exists. 690b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mToneMap.containsKey(c)) { 691b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // begin tone playback. 692b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project startTone(c); 693b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 694b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (DBG) { 695b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project log("ignoring dtmf request for '" + c + "'"); 696b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 697b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 6984472ce7a7e8568b4bb66098c4e4a2e71099167acDavid Brown // Any DTMF keypress counts as explicit "user activity". 6994472ce7a7e8568b4bb66098c4e4a2e71099167acDavid Brown PhoneApp.getInstance().pokeUserActivity(); 700b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 701b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 702b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 703b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Clears out the display of "DTMF digits typed so far" that's kept in 704dfa83d531cdb88513f09e913424b7a16628b37d3David Brown * mDialpadDigits. 705b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 706b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * The InCallScreen is responsible for calling this method any time a 707b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * new call becomes active (or, more simply, any time a call ends). 708b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This is how we make sure that the "history" of DTMF digits you type 709b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * doesn't persist from one call to the next. 710b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 711b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * TODO: it might be more elegent if the dialpad itself could remember 712b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * the call that we're associated with, and clear the digits if the 713b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * "current call" has changed since last time. (This would require 714b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * some unique identifier that's different for each call. We can't 715b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * just use the foreground Call object, since that's a singleton that 716b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * lasts the whole life of the phone process. Instead, maybe look at 717b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * the Connection object that comes back from getEarliestConnection()? 718b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Or getEarliestConnectTime()?) 719b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 720b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Or to be even fancier, we could keep a mapping of *multiple* 721b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * "active calls" to DTMF strings. That way you could have two lines 722b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * in use and swap calls multiple times, and we'd still remember the 723b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * digits for each call. (But that's such an obscure use case that 724b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * it's probably not worth the extra complexity.) 725b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 726b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void clearDigits() { 727b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("clearDigits()..."); 728b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 729b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mDialpadDigits != null) { 730b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDialpadDigits.setText(""); 731b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 732b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 733b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 734b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 73551eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon * Plays the local tone based the phone type. 736b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 73751eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon public void startTone(char c) { 73851eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // Only play the tone if it exists. 73951eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (!mToneMap.containsKey(c)) { 74051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon return; 74151eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon } 74251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // Read the settings as it may be changed by the user during the call 7437ede0c06e06bdb40aabccb52efab21cb85464904Hung-ying Tyan Phone phone = mCM.getFgPhone(); 7447ede0c06e06bdb40aabccb52efab21cb85464904Hung-ying Tyan mShortTone = TelephonyCapabilities.useShortDtmfTones(phone, phone.getContext()); 74551eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon 746d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville if (DBG) log("startDtmfTone()..."); 747b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 74851eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // For Short DTMF we need to play the local tone for fixed duration 74951eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (mShortTone) { 75051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon sendShortDtmfToNetwork(c); 75151eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon } else { 75251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // Pass as a char to be sent to network 75351eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon Log.i(LOG_TAG, "send long dtmf for " + c); 7547ede0c06e06bdb40aabccb52efab21cb85464904Hung-ying Tyan mCM.startDtmf(c); 755b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 75651eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon startLocalToneIfNeeded(c); 757b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 758b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 759b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 76051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon * Plays the local tone based the phone type. 761b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 76251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon public void startLocalToneIfNeeded(char c) { 76351eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // if local tone playback is enabled, start it. 76451eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // Only play the tone if it exists. 76551eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (!mToneMap.containsKey(c)) { 76651eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon return; 76751eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon } 76851eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (mLocalToneEnabled) { 769b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project synchronized (mToneGeneratorLock) { 770b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mToneGenerator == null) { 77151eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (DBG) log("startDtmfTone: mToneGenerator == null, tone: " + c); 772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 77351eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (DBG) log("starting local tone " + c); 77451eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon int toneDuration = -1; 77551eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (mShortTone) { 77651eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon toneDuration = DTMF_DURATION_MS; 77751eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon } 77851eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mToneGenerator.startTone(mToneMap.get(c), toneDuration); 779b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 780b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 781b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 782b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 783b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 784b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 785b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Check to see if the keyEvent is dialable. 786b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 787b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean isKeyEventAcceptable (KeyEvent event) { 788b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return (mDialerKeyListener != null && mDialerKeyListener.isKeyEventAcceptable(event)); 789b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 790b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 791b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 792b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * static logging method 793b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 794b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static void log(String msg) { 795b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.d(LOG_TAG, msg); 796b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 797d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 798d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville /** 799d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville * Stops the local tone based on the phone type. 800d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville */ 80151eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon public void stopTone() { 80251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (!mShortTone) { 80351eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (DBG) log("stopping remote tone."); 8047ede0c06e06bdb40aabccb52efab21cb85464904Hung-ying Tyan mCM.stopDtmf(); 80551eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon stopLocalToneIfNeeded(); 806d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 807d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 808d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 809d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville /** 81051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon * Stops the local tone based on the phone type. 81199e0909905733fbc88300bdc4f475b1f6056388eZhu Kuanting */ 81251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon public void stopLocalToneIfNeeded() { 81351eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (!mShortTone) { 81451eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (DBG) log("stopping remote tone."); 81551eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // if local tone playback is enabled, stop it. 81651eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (DBG) log("trying to stop local tone..."); 81751eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (mLocalToneEnabled) { 81851eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon synchronized (mToneGeneratorLock) { 81951eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (mToneGenerator == null) { 82051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (DBG) log("stopLocalTone: mToneGenerator == null"); 82151eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon } else { 82251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (DBG) log("stopping local tone."); 82351eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mToneGenerator.stopTone(); 82480fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu } 82580fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu } 826d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 827d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 828d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 829d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 830d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville /** 831d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville * Sends the dtmf character over the network for short DTMF settings 83280fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu * When the characters are entered in quick succession, 83380fd5ab27e6a7df77e6e74e819f1a422f0f3fda8Peng Zhu * the characters are queued before sending over the network. 834d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville */ 835d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville private void sendShortDtmfToNetwork(char dtmfDigit) { 836d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville synchronized (mDTMFQueue) { 837d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville if (mDTMFBurstCnfPending == true) { 838d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville // Insert the dtmf char to the queue 839d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville mDTMFQueue.add(new Character(dtmfDigit)); 840d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } else { 841d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville String dtmfStr = Character.toString(dtmfDigit); 842dfa83d531cdb88513f09e913424b7a16628b37d3David Brown Log.i(LOG_TAG, "dtmfsent = " + dtmfStr); 843fa08be2879b66dc61a8e0b5a85dfdd7ef942570bHung-ying Tyan mCM.sendBurstDtmf(dtmfStr, 0, 0, mHandler.obtainMessage(DTMF_SEND_CNF)); 844d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville // Set flag to indicate wait for Telephony confirmation. 845d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville mDTMFBurstCnfPending = true; 846d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 847d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 848d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 849d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville 850d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville /** 851d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville * Handles Burst Dtmf Confirmation from the Framework. 852d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville */ 853d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville void handleBurstDtmfConfirmation() { 854d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville Character dtmfChar = null; 855dfa83d531cdb88513f09e913424b7a16628b37d3David Brown synchronized (mDTMFQueue) { 856d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville mDTMFBurstCnfPending = false; 857dfa83d531cdb88513f09e913424b7a16628b37d3David Brown if (!mDTMFQueue.isEmpty()) { 858d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville dtmfChar = mDTMFQueue.remove(); 859d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville Log.i(LOG_TAG, "The dtmf character removed from queue" + dtmfChar); 860d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 861d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 862d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville if (dtmfChar != null) { 863d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville sendShortDtmfToNetwork(dtmfChar); 864d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 865d533a71d64507e33d78dc65aa2521eacb5f8bb25Wink Saville } 866b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project} 867