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; 68a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon private final boolean mIsOutgoing; 69c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon // Queue of pending short-DTMF characters. 70c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private final Queue<Character> mDtmfQueue = new LinkedList<>(); 715c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon private final EmergencyTonePlayer mEmergencyTonePlayer; 72625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn 73c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon // Indicates that the DTMF confirmation from telephony is pending. 74c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private boolean mDtmfBurstConfirmationPending = false; 75a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon private boolean mIsCallWaiting; 76a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 775c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon CdmaConnection( 785c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon Connection connection, 795c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon EmergencyTonePlayer emergencyTonePlayer, 805c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon boolean allowMute, 811cf18c55c3764faa21a6690cebe6d09470ed1200Tyler Gunn boolean isOutgoing, 821cf18c55c3764faa21a6690cebe6d09470ed1200Tyler Gunn String telecomCallId) { 831cf18c55c3764faa21a6690cebe6d09470ed1200Tyler Gunn super(connection, telecomCallId); 845c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon mEmergencyTonePlayer = emergencyTonePlayer; 85625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn mAllowMute = allowMute; 86a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon mIsOutgoing = isOutgoing; 87a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon mIsCallWaiting = connection != null && connection.getState() == Call.State.WAITING; 88faa1ed26356d75382d512e76244493851e8dcb24Omkar Kolangade boolean isImsCall = getOriginalConnection() instanceof ImsPhoneConnection; 89faa1ed26356d75382d512e76244493851e8dcb24Omkar Kolangade // Start call waiting timer for CDMA waiting call. 90faa1ed26356d75382d512e76244493851e8dcb24Omkar Kolangade if (mIsCallWaiting && !isImsCall) { 91a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon startCallWaitingTimer(); 92a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 936f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal } 942537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad 952537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad /** {@inheritDoc} */ 962537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad @Override 97ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onPlayDtmfTone(char digit) { 98c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon if (useBurstDtmf()) { 99c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon Log.i(this, "sending dtmf digit as burst"); 100c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon sendShortDtmfToNetwork(digit); 101c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } else { 102c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon Log.i(this, "sending dtmf digit directly"); 103c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon getPhone().startDtmf(digit); 1043199aa7f8bcb48569eb8289abc055ba0f8496ba8Sailesh Nepal } 1052537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad } 1062537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad 1072537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad /** {@inheritDoc} */ 1082537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad @Override 109ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onStopDtmfTone() { 110c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon if (!useBurstDtmf()) { 111c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon getPhone().stopDtmf(); 112c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 1132537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad } 114f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal 115f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal @Override 116a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon public void onReject() { 117a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon Connection connection = getOriginalConnection(); 118a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon if (connection != null) { 119a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon switch (connection.getState()) { 120a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon case INCOMING: 121a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon // Normal ringing calls are handled the generic way. 122a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon super.onReject(); 123a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon break; 124a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon case WAITING: 125a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon hangupCallWaiting(DisconnectCause.INCOMING_REJECTED); 126a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon break; 127a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon default: 128a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon Log.e(this, new Exception(), "Rejecting a non-ringing call"); 129a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon // might as well hang this up, too. 130a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon super.onReject(); 131a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon break; 132a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 133a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 134a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 135a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 136a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon @Override 137a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon public void onAnswer() { 138a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon mHandler.removeMessages(MSG_CALL_WAITING_MISSED); 139a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon super.onAnswer(); 140a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 141a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 14233464599cc0083dba146db75cecea3ee354888c9Tyler Gunn /** 14333464599cc0083dba146db75cecea3ee354888c9Tyler Gunn * Clones the current {@link CdmaConnection}. 14433464599cc0083dba146db75cecea3ee354888c9Tyler Gunn * <p> 14533464599cc0083dba146db75cecea3ee354888c9Tyler Gunn * Listeners are not copied to the new instance. 14633464599cc0083dba146db75cecea3ee354888c9Tyler Gunn * 14733464599cc0083dba146db75cecea3ee354888c9Tyler Gunn * @return The cloned connection. 14833464599cc0083dba146db75cecea3ee354888c9Tyler Gunn */ 14933464599cc0083dba146db75cecea3ee354888c9Tyler Gunn @Override 15033464599cc0083dba146db75cecea3ee354888c9Tyler Gunn public TelephonyConnection cloneConnection() { 15133464599cc0083dba146db75cecea3ee354888c9Tyler Gunn CdmaConnection cdmaConnection = new CdmaConnection(getOriginalConnection(), 1521cf18c55c3764faa21a6690cebe6d09470ed1200Tyler Gunn mEmergencyTonePlayer, mAllowMute, mIsOutgoing, getTelecomCallId()); 15333464599cc0083dba146db75cecea3ee354888c9Tyler Gunn return cdmaConnection; 15433464599cc0083dba146db75cecea3ee354888c9Tyler Gunn } 15533464599cc0083dba146db75cecea3ee354888c9Tyler Gunn 156a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon @Override 157c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen public void onStateChanged(int state) { 158a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon Connection originalConnection = getOriginalConnection(); 159a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon mIsCallWaiting = originalConnection != null && 160a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon originalConnection.getState() == Call.State.WAITING; 1615c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon 1623d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar if (mEmergencyTonePlayer != null) { 1633d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar if (state == android.telecom.Connection.STATE_DIALING) { 1643d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar if (isEmergency()) { 1653d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar mEmergencyTonePlayer.start(); 1663d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar } 1673d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar } else { 1683d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar // No need to check if it is an emergency call, since it is a no-op if it 1693d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar // isn't started. 1703d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar mEmergencyTonePlayer.stop(); 1715c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon } 1725c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon } 1735c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon 174c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen super.onStateChanged(state); 175a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 176a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 177a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon @Override 1783cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad protected int buildConnectionCapabilities() { 1793cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad int capabilities = super.buildConnectionCapabilities(); 180625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn if (mAllowMute) { 1813cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad capabilities |= CAPABILITY_MUTE; 182625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn } 183f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal return capabilities; 184f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal } 185a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 186cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee @Override 1875149f9cd57ed16f3e4560fc96a0b2b7d1d6095dbTyler Gunn public void performConference(android.telecom.Connection otherConnection) { 188cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee if (isImsConnection()) { 189cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee super.performConference(otherConnection); 190cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee } else { 191cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee Log.w(this, "Non-IMS CDMA Connection attempted to call performConference."); 192cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee } 193cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee } 194cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee 195a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon void forceAsDialing(boolean isDialing) { 196a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon if (isDialing) { 197bd8589eb7836206246f035edf9c51acef6e6a14bRoshan Pius setStateOverride(Call.State.DIALING); 198a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } else { 199bd8589eb7836206246f035edf9c51acef6e6a14bRoshan Pius resetStateOverride(); 200a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 201a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 202a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 203a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon boolean isOutgoing() { 204a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon return mIsOutgoing; 205a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 206a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 207a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon boolean isCallWaiting() { 208a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon return mIsCallWaiting; 209a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 210a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 211a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon /** 212a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * We do not get much in the way of confirmation for Cdma call waiting calls. There is no 213a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * indication that a rejected call succeeded, a call waiting call has stopped. Instead we 214a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * simulate this for the user. We allow TIMEOUT_CALL_WAITING_MILLIS milliseconds before we 215a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * assume that the call was missed and reject it ourselves. reject the call automatically. 216a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon */ 217a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon private void startCallWaitingTimer() { 218a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon mHandler.sendEmptyMessageDelayed(MSG_CALL_WAITING_MISSED, TIMEOUT_CALL_WAITING_MILLIS); 219a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 220a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon 221aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee private void hangupCallWaiting(int telephonyDisconnectCause) { 222a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon Connection originalConnection = getOriginalConnection(); 223a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon if (originalConnection != null) { 224a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon try { 225a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon originalConnection.hangup(); 226a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } catch (CallStateException e) { 227a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon Log.e(this, e, "Failed to hangup call waiting call"); 228a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 229aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(telephonyDisconnectCause)); 230a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 231a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon } 232c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 233c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon /** 234c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon * Read the settings to determine which type of DTMF method this CDMA phone calls. 235c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon */ 236c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private boolean useBurstDtmf() { 2373c96d1a1d0190d99c2c0f3ecf96d09a777d9b32fAndrew Lee if (isImsConnection()) { 2389ed62ca34427e4f61368f6315f24f563a55b1924Libin.Tang@motorola.com Log.d(this,"in ims call, return false"); 2399ed62ca34427e4f61368f6315f24f563a55b1924Libin.Tang@motorola.com return false; 2409ed62ca34427e4f61368f6315f24f563a55b1924Libin.Tang@motorola.com } 241c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon int dtmfTypeSetting = Settings.System.getInt( 242c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon getPhone().getContext().getContentResolver(), 243c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 244fb7f92eaad86b839bcd94d2814933a151f39a480Andrew Lee SettingsConstants.DTMF_TONE_TYPE_NORMAL); 245fb7f92eaad86b839bcd94d2814933a151f39a480Andrew Lee return dtmfTypeSetting == SettingsConstants.DTMF_TONE_TYPE_NORMAL; 246c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 247c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 248c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private void sendShortDtmfToNetwork(char digit) { 249c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon synchronized(mDtmfQueue) { 250c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon if (mDtmfBurstConfirmationPending) { 251c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon mDtmfQueue.add(new Character(digit)); 252c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } else { 253c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon sendBurstDtmfStringLocked(Character.toString(digit)); 254c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 255c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 256c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 257c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 258c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private void sendBurstDtmfStringLocked(String dtmfString) { 259c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon getPhone().sendBurstDtmf( 260c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon dtmfString, 0, 0, mHandler.obtainMessage(MSG_DTMF_SEND_CONFIRMATION)); 261c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon mDtmfBurstConfirmationPending = true; 262c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 263c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 264c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon private void handleBurstDtmfConfirmation() { 265c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon String dtmfDigits = null; 266c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon synchronized(mDtmfQueue) { 267c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon mDtmfBurstConfirmationPending = false; 268c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon if (!mDtmfQueue.isEmpty()) { 269c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon StringBuilder builder = new StringBuilder(mDtmfQueue.size()); 270c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon while (!mDtmfQueue.isEmpty()) { 271c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon builder.append(mDtmfQueue.poll()); 272c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 273c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon dtmfDigits = builder.toString(); 274c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon 275c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon // It would be nice to log the digit, but since DTMF digits can be passwords 276c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon // to things, or other secure account numbers, we want to keep it away from 277c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon // the logs. 278c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon Log.i(this, "%d dtmf character[s] removed from the queue", dtmfDigits.length()); 279c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 280c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon if (dtmfDigits != null) { 281c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon sendBurstDtmfStringLocked(dtmfDigits); 282c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 283c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 284c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon } 2855c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon 2865c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon private boolean isEmergency() { 2875c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon Phone phone = getPhone(); 2885c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon return phone != null && 2895c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon PhoneNumberUtils.isLocalEmergencyNumber( 2905c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon phone.getContext(), getAddress().getSchemeSpecificPart()); 2915c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon } 292816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn 293816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn /** 294816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn * Called when ECM mode is exited; set the connection to allow mute and update the connection 295816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn * capabilities. 296816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn */ 297816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn @Override 298816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn protected void handleExitedEcmMode() { 299816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn // We allow mute upon existing ECM mode and rebuild the capabilities. 300816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn mAllowMute = true; 301816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn super.handleExitedEcmMode(); 302816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn } 3036f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal} 304