16f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal/* 26f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * Copyright (C) 2014 The Android Open Source Project 36f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * 46f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * Licensed under the Apache License, Version 2.0 (the "License"); 56f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * you may not use this file except in compliance with the License. 66f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * You may obtain a copy of the License at 76f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * 86f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * http://www.apache.org/licenses/LICENSE-2.0 96f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * 106f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * Unless required by applicable law or agreed to in writing, software 116f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * distributed under the License is distributed on an "AS IS" BASIS, 126f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * See the License for the specific language governing permissions and 146f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal * limitations under the License. 156f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal */ 166f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal 176f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepalpackage com.android.services.telephony; 186f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal 19a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordonimport android.os.Handler; 20a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordonimport android.os.Message; 21f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal 22c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordonimport android.provider.Settings; 23a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordonimport android.telephony.DisconnectCause; 245c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordonimport android.telephony.PhoneNumberUtils; 25a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 26a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordonimport com.android.internal.telephony.Call; 27a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordonimport com.android.internal.telephony.CallStateException; 286a6e769af983b973a67cff3e8926597525835aa9Ihab Awadimport com.android.internal.telephony.Connection; 29faa1ed26356d75382d512e76244493851e8dcb24Omkar Kolangadeimport com.android.internal.telephony.imsphone.ImsPhoneConnection; 305c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordonimport com.android.internal.telephony.Phone; 31fb7f92eaad86b839bcd94d2814933a151f39a480Andrew Leeimport com.android.phone.settings.SettingsConstants; 32c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 33c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordonimport java.util.LinkedList; 34c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordonimport java.util.Queue; 356f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal 366f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal/** 376a6e769af983b973a67cff3e8926597525835aa9Ihab Awad * Manages a single phone call handled by CDMA. 386f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal */ 393199aa7f8bcb48569eb8289abc055ba0f8496ba8Sailesh Nepalfinal class CdmaConnection extends TelephonyConnection { 40625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn 41a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon private static final int MSG_CALL_WAITING_MISSED = 1; 42c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private static final int MSG_DTMF_SEND_CONFIRMATION = 2; 43a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon private static final int TIMEOUT_CALL_WAITING_MILLIS = 20 * 1000; 44a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 45a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon private final Handler mHandler = new Handler() { 46a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 47a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon /** ${inheritDoc} */ 48a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon @Override 49a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon public void handleMessage(Message msg) { 50a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon switch (msg.what) { 51a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon case MSG_CALL_WAITING_MISSED: 52a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon hangupCallWaiting(DisconnectCause.INCOMING_MISSED); 53a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon break; 54c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon case MSG_DTMF_SEND_CONFIRMATION: 55c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon handleBurstDtmfConfirmation(); 56c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon break; 57a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon default: 58a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon break; 59a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 60a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 61a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 62a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon }; 63a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 64625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn /** 65625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn * {@code True} if the CDMA connection should allow mute. 66625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn */ 67816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn private boolean mAllowMute; 68c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon // Queue of pending short-DTMF characters. 69c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private final Queue<Character> mDtmfQueue = new LinkedList<>(); 705c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon private final EmergencyTonePlayer mEmergencyTonePlayer; 71625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn 72c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon // Indicates that the DTMF confirmation from telephony is pending. 73c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private boolean mDtmfBurstConfirmationPending = false; 74a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon private boolean mIsCallWaiting; 75a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 765c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon CdmaConnection( 775c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon Connection connection, 785c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon EmergencyTonePlayer emergencyTonePlayer, 795c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon boolean allowMute, 801cf18c55c3764faa21a6690cebe6d09470ed1200Tyler Gunn boolean isOutgoing, 811cf18c55c3764faa21a6690cebe6d09470ed1200Tyler Gunn String telecomCallId) { 8257c362606bdc175152c210653a9d613c7572a59eTyler Gunn super(connection, telecomCallId, isOutgoing); 835c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon mEmergencyTonePlayer = emergencyTonePlayer; 84625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn mAllowMute = allowMute; 85a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon mIsCallWaiting = connection != null && connection.getState() == Call.State.WAITING; 86faa1ed26356d75382d512e76244493851e8dcb24Omkar Kolangade boolean isImsCall = getOriginalConnection() instanceof ImsPhoneConnection; 87faa1ed26356d75382d512e76244493851e8dcb24Omkar Kolangade // Start call waiting timer for CDMA waiting call. 88faa1ed26356d75382d512e76244493851e8dcb24Omkar Kolangade if (mIsCallWaiting && !isImsCall) { 89a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon startCallWaitingTimer(); 90a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 916f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal } 922537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad 932537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad /** {@inheritDoc} */ 942537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad @Override 95ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onPlayDtmfTone(char digit) { 96c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon if (useBurstDtmf()) { 97c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon Log.i(this, "sending dtmf digit as burst"); 98c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon sendShortDtmfToNetwork(digit); 99c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } else { 100c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon Log.i(this, "sending dtmf digit directly"); 101c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon getPhone().startDtmf(digit); 1023199aa7f8bcb48569eb8289abc055ba0f8496ba8Sailesh Nepal } 1032537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad } 1042537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad 1052537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad /** {@inheritDoc} */ 1062537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad @Override 107ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onStopDtmfTone() { 108c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon if (!useBurstDtmf()) { 109c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon getPhone().stopDtmf(); 110c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 1112537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad } 112f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal 113f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal @Override 114a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon public void onReject() { 115a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon Connection connection = getOriginalConnection(); 116a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon if (connection != null) { 117a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon switch (connection.getState()) { 118a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon case INCOMING: 119a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon // Normal ringing calls are handled the generic way. 120a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon super.onReject(); 121a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon break; 122a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon case WAITING: 123a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon hangupCallWaiting(DisconnectCause.INCOMING_REJECTED); 124a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon break; 125a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon default: 126a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon Log.e(this, new Exception(), "Rejecting a non-ringing call"); 127a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon // might as well hang this up, too. 128a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon super.onReject(); 129a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon break; 130a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 131a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 132a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 133a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 134a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon @Override 135a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon public void onAnswer() { 136a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon mHandler.removeMessages(MSG_CALL_WAITING_MISSED); 137a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon super.onAnswer(); 138a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 139a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 14033464599cc0083dba146db75cecea3ee354888c9Tyler Gunn /** 14133464599cc0083dba146db75cecea3ee354888c9Tyler Gunn * Clones the current {@link CdmaConnection}. 14233464599cc0083dba146db75cecea3ee354888c9Tyler Gunn * <p> 14333464599cc0083dba146db75cecea3ee354888c9Tyler Gunn * Listeners are not copied to the new instance. 14433464599cc0083dba146db75cecea3ee354888c9Tyler Gunn * 14533464599cc0083dba146db75cecea3ee354888c9Tyler Gunn * @return The cloned connection. 14633464599cc0083dba146db75cecea3ee354888c9Tyler Gunn */ 14733464599cc0083dba146db75cecea3ee354888c9Tyler Gunn @Override 14833464599cc0083dba146db75cecea3ee354888c9Tyler Gunn public TelephonyConnection cloneConnection() { 14933464599cc0083dba146db75cecea3ee354888c9Tyler Gunn CdmaConnection cdmaConnection = new CdmaConnection(getOriginalConnection(), 1501cf18c55c3764faa21a6690cebe6d09470ed1200Tyler Gunn mEmergencyTonePlayer, mAllowMute, mIsOutgoing, getTelecomCallId()); 15133464599cc0083dba146db75cecea3ee354888c9Tyler Gunn return cdmaConnection; 15233464599cc0083dba146db75cecea3ee354888c9Tyler Gunn } 15333464599cc0083dba146db75cecea3ee354888c9Tyler Gunn 154a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon @Override 155c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen public void onStateChanged(int state) { 156a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon Connection originalConnection = getOriginalConnection(); 157a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon mIsCallWaiting = originalConnection != null && 158a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon originalConnection.getState() == Call.State.WAITING; 1595c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon 1603d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar if (mEmergencyTonePlayer != null) { 1613d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar if (state == android.telecom.Connection.STATE_DIALING) { 1623d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar if (isEmergency()) { 1633d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar mEmergencyTonePlayer.start(); 1643d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar } 1653d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar } else { 1663d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar // No need to check if it is an emergency call, since it is a no-op if it 1673d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar // isn't started. 1683d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar mEmergencyTonePlayer.stop(); 1695c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon } 1705c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon } 1715c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon 172c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen super.onStateChanged(state); 173a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 174a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 175a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon @Override 1763cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad protected int buildConnectionCapabilities() { 1773cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad int capabilities = super.buildConnectionCapabilities(); 178625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn if (mAllowMute) { 1793cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad capabilities |= CAPABILITY_MUTE; 180625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn } 181f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal return capabilities; 182f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal } 183a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 184cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee @Override 1855149f9cd57ed16f3e4560fc96a0b2b7d1d6095dbTyler Gunn public void performConference(android.telecom.Connection otherConnection) { 186cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee if (isImsConnection()) { 187cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee super.performConference(otherConnection); 188cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee } else { 189cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee Log.w(this, "Non-IMS CDMA Connection attempted to call performConference."); 190cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee } 191cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee } 192cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee 193a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon void forceAsDialing(boolean isDialing) { 194a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon if (isDialing) { 195bd8589eb7836206246f035edf9c51acef6e6a14bRoshan Pius setStateOverride(Call.State.DIALING); 196a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } else { 197bd8589eb7836206246f035edf9c51acef6e6a14bRoshan Pius resetStateOverride(); 198a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 199a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 200a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 201a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon boolean isOutgoing() { 202a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon return mIsOutgoing; 203a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 204a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 205a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon boolean isCallWaiting() { 206a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon return mIsCallWaiting; 207a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 208a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 209a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon /** 210a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * We do not get much in the way of confirmation for Cdma call waiting calls. There is no 211a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * indication that a rejected call succeeded, a call waiting call has stopped. Instead we 212a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * simulate this for the user. We allow TIMEOUT_CALL_WAITING_MILLIS milliseconds before we 213a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * assume that the call was missed and reject it ourselves. reject the call automatically. 214a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon */ 215a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon private void startCallWaitingTimer() { 216a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon mHandler.sendEmptyMessageDelayed(MSG_CALL_WAITING_MISSED, TIMEOUT_CALL_WAITING_MILLIS); 217a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 218a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 219aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee private void hangupCallWaiting(int telephonyDisconnectCause) { 220a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon Connection originalConnection = getOriginalConnection(); 221a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon if (originalConnection != null) { 222a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon try { 223a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon originalConnection.hangup(); 224a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } catch (CallStateException e) { 225a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon Log.e(this, e, "Failed to hangup call waiting call"); 226a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 227aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(telephonyDisconnectCause)); 228a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 229a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 230c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 231c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon /** 232c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon * Read the settings to determine which type of DTMF method this CDMA phone calls. 233c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon */ 234c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private boolean useBurstDtmf() { 2353c96d1a1d0190d99c2c0f3ecf96d09a777d9b32fAndrew Lee if (isImsConnection()) { 2369ed62ca34427e4f61368f6315f24f563a55b1924Libin.Tang@motorola.com Log.d(this,"in ims call, return false"); 2379ed62ca34427e4f61368f6315f24f563a55b1924Libin.Tang@motorola.com return false; 2389ed62ca34427e4f61368f6315f24f563a55b1924Libin.Tang@motorola.com } 239c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon int dtmfTypeSetting = Settings.System.getInt( 240c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon getPhone().getContext().getContentResolver(), 241c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 242fb7f92eaad86b839bcd94d2814933a151f39a480Andrew Lee SettingsConstants.DTMF_TONE_TYPE_NORMAL); 243fb7f92eaad86b839bcd94d2814933a151f39a480Andrew Lee return dtmfTypeSetting == SettingsConstants.DTMF_TONE_TYPE_NORMAL; 244c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 245c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 246c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private void sendShortDtmfToNetwork(char digit) { 247c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon synchronized(mDtmfQueue) { 248c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon if (mDtmfBurstConfirmationPending) { 249c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon mDtmfQueue.add(new Character(digit)); 250c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } else { 251c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon sendBurstDtmfStringLocked(Character.toString(digit)); 252c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 253c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 254c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 255c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 256c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private void sendBurstDtmfStringLocked(String dtmfString) { 257c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon getPhone().sendBurstDtmf( 258c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon dtmfString, 0, 0, mHandler.obtainMessage(MSG_DTMF_SEND_CONFIRMATION)); 259c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon mDtmfBurstConfirmationPending = true; 260c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 261c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 262c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private void handleBurstDtmfConfirmation() { 263c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon String dtmfDigits = null; 264c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon synchronized(mDtmfQueue) { 265c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon mDtmfBurstConfirmationPending = false; 266c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon if (!mDtmfQueue.isEmpty()) { 267c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon StringBuilder builder = new StringBuilder(mDtmfQueue.size()); 268c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon while (!mDtmfQueue.isEmpty()) { 269c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon builder.append(mDtmfQueue.poll()); 270c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 271c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon dtmfDigits = builder.toString(); 272c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 273c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon // It would be nice to log the digit, but since DTMF digits can be passwords 274c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon // to things, or other secure account numbers, we want to keep it away from 275c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon // the logs. 276c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon Log.i(this, "%d dtmf character[s] removed from the queue", dtmfDigits.length()); 277c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 278c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon if (dtmfDigits != null) { 279c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon sendBurstDtmfStringLocked(dtmfDigits); 280c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 281c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 282c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 2835c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon 2845c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon private boolean isEmergency() { 2855c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon Phone phone = getPhone(); 2865c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon return phone != null && 2875c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon PhoneNumberUtils.isLocalEmergencyNumber( 2885c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon phone.getContext(), getAddress().getSchemeSpecificPart()); 2895c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon } 290816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn 291816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn /** 292816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn * Called when ECM mode is exited; set the connection to allow mute and update the connection 293816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn * capabilities. 294816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn */ 295816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn @Override 296816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn protected void handleExitedEcmMode() { 297816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn // We allow mute upon existing ECM mode and rebuild the capabilities. 298816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn mAllowMute = true; 299816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn super.handleExitedEcmMode(); 300816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn } 3016f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal} 302