CdmaConnection.java revision 816820e7bcf35be70cf26e534b4767786ff8e83f
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;
295c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordonimport com.android.internal.telephony.Phone;
30fb7f92eaad86b839bcd94d2814933a151f39a480Andrew Leeimport com.android.phone.settings.SettingsConstants;
31c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon
32c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordonimport java.util.LinkedList;
33c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordonimport java.util.Queue;
346f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal
356f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal/**
366a6e769af983b973a67cff3e8926597525835aa9Ihab Awad * Manages a single phone call handled by CDMA.
376f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal */
383199aa7f8bcb48569eb8289abc055ba0f8496ba8Sailesh Nepalfinal class CdmaConnection extends TelephonyConnection {
39625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn
40a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    private static final int MSG_CALL_WAITING_MISSED = 1;
41c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon    private static final int MSG_DTMF_SEND_CONFIRMATION = 2;
42a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    private static final int TIMEOUT_CALL_WAITING_MILLIS = 20 * 1000;
43a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
44a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    private final Handler mHandler = new Handler() {
45a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
46a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        /** ${inheritDoc} */
47a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        @Override
48a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        public void handleMessage(Message msg) {
49a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            switch (msg.what) {
50a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                case MSG_CALL_WAITING_MISSED:
51a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    hangupCallWaiting(DisconnectCause.INCOMING_MISSED);
52a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    break;
53c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                case MSG_DTMF_SEND_CONFIRMATION:
54c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                    handleBurstDtmfConfirmation();
55c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                    break;
56a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                default:
57a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    break;
58a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            }
59a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        }
60a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
61a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    };
62a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
63625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn    /**
64625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn     * {@code True} if the CDMA connection should allow mute.
65625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn     */
66816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn    private boolean mAllowMute;
67a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    private final boolean mIsOutgoing;
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) {
821cf18c55c3764faa21a6690cebe6d09470ed1200Tyler Gunn        super(connection, telecomCallId);
835c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon        mEmergencyTonePlayer = emergencyTonePlayer;
84625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn        mAllowMute = allowMute;
85a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        mIsOutgoing = isOutgoing;
86a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        mIsCallWaiting = connection != null && connection.getState() == Call.State.WAITING;
87a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        if (mIsCallWaiting) {
88a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            startCallWaitingTimer();
89a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        }
906f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal    }
912537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad
922537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad    /** {@inheritDoc} */
932537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad    @Override
94ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onPlayDtmfTone(char digit) {
95c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        if (useBurstDtmf()) {
96c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            Log.i(this, "sending dtmf digit as burst");
97c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            sendShortDtmfToNetwork(digit);
98c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        } else {
99c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            Log.i(this, "sending dtmf digit directly");
100c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            getPhone().startDtmf(digit);
1013199aa7f8bcb48569eb8289abc055ba0f8496ba8Sailesh Nepal        }
1022537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad    }
1032537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad
1042537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad    /** {@inheritDoc} */
1052537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad    @Override
106ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onStopDtmfTone() {
107c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        if (!useBurstDtmf()) {
108c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            getPhone().stopDtmf();
109c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        }
1102537992d67bb2200bf9e8c69fa97481dfc1db202Ihab Awad    }
111f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal
112f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal    @Override
113a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    public void onReject() {
114a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        Connection connection = getOriginalConnection();
115a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        if (connection != null) {
116a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            switch (connection.getState()) {
117a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                case INCOMING:
118a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    // Normal ringing calls are handled the generic way.
119a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    super.onReject();
120a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    break;
121a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                case WAITING:
122a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    hangupCallWaiting(DisconnectCause.INCOMING_REJECTED);
123a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    break;
124a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                default:
125a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    Log.e(this, new Exception(), "Rejecting a non-ringing call");
126a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    // might as well hang this up, too.
127a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    super.onReject();
128a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    break;
129a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            }
130a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        }
131a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
132a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
133a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    @Override
134a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    public void onAnswer() {
135a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        mHandler.removeMessages(MSG_CALL_WAITING_MISSED);
136a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        super.onAnswer();
137a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
138a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
13933464599cc0083dba146db75cecea3ee354888c9Tyler Gunn    /**
14033464599cc0083dba146db75cecea3ee354888c9Tyler Gunn     * Clones the current {@link CdmaConnection}.
14133464599cc0083dba146db75cecea3ee354888c9Tyler Gunn     * <p>
14233464599cc0083dba146db75cecea3ee354888c9Tyler Gunn     * Listeners are not copied to the new instance.
14333464599cc0083dba146db75cecea3ee354888c9Tyler Gunn     *
14433464599cc0083dba146db75cecea3ee354888c9Tyler Gunn     * @return The cloned connection.
14533464599cc0083dba146db75cecea3ee354888c9Tyler Gunn     */
14633464599cc0083dba146db75cecea3ee354888c9Tyler Gunn    @Override
14733464599cc0083dba146db75cecea3ee354888c9Tyler Gunn    public TelephonyConnection cloneConnection() {
14833464599cc0083dba146db75cecea3ee354888c9Tyler Gunn        CdmaConnection cdmaConnection = new CdmaConnection(getOriginalConnection(),
1491cf18c55c3764faa21a6690cebe6d09470ed1200Tyler Gunn                mEmergencyTonePlayer, mAllowMute, mIsOutgoing, getTelecomCallId());
15033464599cc0083dba146db75cecea3ee354888c9Tyler Gunn        return cdmaConnection;
15133464599cc0083dba146db75cecea3ee354888c9Tyler Gunn    }
15233464599cc0083dba146db75cecea3ee354888c9Tyler Gunn
153a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    @Override
154c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen    public void onStateChanged(int state) {
155a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        Connection originalConnection = getOriginalConnection();
156a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        mIsCallWaiting = originalConnection != null &&
157a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                originalConnection.getState() == Call.State.WAITING;
1585c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon
1593d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar        if (mEmergencyTonePlayer != null) {
1603d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar            if (state == android.telecom.Connection.STATE_DIALING) {
1613d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar                if (isEmergency()) {
1623d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar                    mEmergencyTonePlayer.start();
1633d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar                }
1643d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar            } else {
1653d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar                // No need to check if it is an emergency call, since it is a no-op if it
1663d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar                // isn't started.
1673d8ea0e60c00436c4c3596d83fa164640f10b098Rekha Kumar                mEmergencyTonePlayer.stop();
1685c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon            }
1695c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon        }
1705c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon
171c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen        super.onStateChanged(state);
172a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
173a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
174a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    @Override
1753cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad    protected int buildConnectionCapabilities() {
1763cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad        int capabilities = super.buildConnectionCapabilities();
177625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn        if (mAllowMute) {
1783cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad            capabilities |= CAPABILITY_MUTE;
179625eb0b8f6e52e7ac1b5a499c5e1964812911913Tyler Gunn        }
180f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal        return capabilities;
181f64d8ca4278e0bfb3afd9023058f86dfc8e92ff6Sailesh Nepal    }
182a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
183cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee    @Override
184cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee    public void performConference(TelephonyConnection otherConnection) {
185cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee        if (isImsConnection()) {
186cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee            super.performConference(otherConnection);
187cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee        } else {
188cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee            Log.w(this, "Non-IMS CDMA Connection attempted to call performConference.");
189cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee        }
190cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee    }
191cb101f68bbaf5a050b422b6cbc29bb20d11078a4Andrew Lee
192a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    void forceAsDialing(boolean isDialing) {
193a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        if (isDialing) {
194bd8589eb7836206246f035edf9c51acef6e6a14bRoshan Pius            setStateOverride(Call.State.DIALING);
195a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        } else {
196bd8589eb7836206246f035edf9c51acef6e6a14bRoshan Pius            resetStateOverride();
197a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        }
198a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
199a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
200a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    boolean isOutgoing() {
201a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        return mIsOutgoing;
202a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
203a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
204a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    boolean isCallWaiting() {
205a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        return mIsCallWaiting;
206a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
207a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
208a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    /**
209a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon     * We do not get much in the way of confirmation for Cdma call waiting calls. There is no
210a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon     * indication that a rejected call succeeded, a call waiting call has stopped. Instead we
211a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon     * simulate this for the user. We allow TIMEOUT_CALL_WAITING_MILLIS milliseconds before we
212a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon     * assume that the call was missed and reject it ourselves. reject the call automatically.
213a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon     */
214a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    private void startCallWaitingTimer() {
215a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        mHandler.sendEmptyMessageDelayed(MSG_CALL_WAITING_MISSED, TIMEOUT_CALL_WAITING_MILLIS);
216a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
217a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
218aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee    private void hangupCallWaiting(int telephonyDisconnectCause) {
219a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        Connection originalConnection = getOriginalConnection();
220a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        if (originalConnection != null) {
221a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            try {
222a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                originalConnection.hangup();
223a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            } catch (CallStateException e) {
224a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                Log.e(this, e, "Failed to hangup call waiting call");
225a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            }
226aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee            setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(telephonyDisconnectCause));
227a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        }
228a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
229c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon
230c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon    /**
231c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon     * Read the settings to determine which type of DTMF method this CDMA phone calls.
232c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon     */
233c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon    private boolean useBurstDtmf() {
2343c96d1a1d0190d99c2c0f3ecf96d09a777d9b32fAndrew Lee        if (isImsConnection()) {
2359ed62ca34427e4f61368f6315f24f563a55b1924Libin.Tang@motorola.com            Log.d(this,"in ims call, return false");
2369ed62ca34427e4f61368f6315f24f563a55b1924Libin.Tang@motorola.com            return false;
2379ed62ca34427e4f61368f6315f24f563a55b1924Libin.Tang@motorola.com        }
238c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        int dtmfTypeSetting = Settings.System.getInt(
239c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                getPhone().getContext().getContentResolver(),
240c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                Settings.System.DTMF_TONE_TYPE_WHEN_DIALING,
241fb7f92eaad86b839bcd94d2814933a151f39a480Andrew Lee                SettingsConstants.DTMF_TONE_TYPE_NORMAL);
242fb7f92eaad86b839bcd94d2814933a151f39a480Andrew Lee        return dtmfTypeSetting == SettingsConstants.DTMF_TONE_TYPE_NORMAL;
243c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon    }
244c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon
245c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon    private void sendShortDtmfToNetwork(char digit) {
246c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        synchronized(mDtmfQueue) {
247c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            if (mDtmfBurstConfirmationPending) {
248c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                mDtmfQueue.add(new Character(digit));
249c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            } else {
250c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                sendBurstDtmfStringLocked(Character.toString(digit));
251c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            }
252c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        }
253c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon    }
254c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon
255c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon    private void sendBurstDtmfStringLocked(String dtmfString) {
256c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        getPhone().sendBurstDtmf(
257c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                dtmfString, 0, 0, mHandler.obtainMessage(MSG_DTMF_SEND_CONFIRMATION));
258c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        mDtmfBurstConfirmationPending = true;
259c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon    }
260c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon
261c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon    private void handleBurstDtmfConfirmation() {
262c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        String dtmfDigits = null;
263c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        synchronized(mDtmfQueue) {
264c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            mDtmfBurstConfirmationPending = false;
265c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            if (!mDtmfQueue.isEmpty()) {
266c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                StringBuilder builder = new StringBuilder(mDtmfQueue.size());
267c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                while (!mDtmfQueue.isEmpty()) {
268c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                    builder.append(mDtmfQueue.poll());
269c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                }
270c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                dtmfDigits = builder.toString();
271c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon
272c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                // It would be nice to log the digit, but since DTMF digits can be passwords
273c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                // to things, or other secure account numbers, we want to keep it away from
274c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                // the logs.
275c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                Log.i(this, "%d dtmf character[s] removed from the queue", dtmfDigits.length());
276c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            }
277c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            if (dtmfDigits != null) {
278c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon                sendBurstDtmfStringLocked(dtmfDigits);
279c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon            }
280c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon        }
281c14ca9a77063d42e94d3f6c3f5c090892aa5c8a3Santos Cordon    }
2825c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon
2835c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon    private boolean isEmergency() {
2845c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon        Phone phone = getPhone();
2855c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon        return phone != null &&
2865c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon                PhoneNumberUtils.isLocalEmergencyNumber(
2875c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon                    phone.getContext(), getAddress().getSchemeSpecificPart());
2885c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon    }
289816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn
290816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn    /**
291816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn     * Called when ECM mode is exited; set the connection to allow mute and update the connection
292816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn     * capabilities.
293816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn     */
294816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn    @Override
295816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn    protected void handleExitedEcmMode() {
296816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn        // We allow mute upon existing ECM mode and rebuild the capabilities.
297816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn        mAllowMute = true;
298816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn        super.handleExitedEcmMode();
299816820e7bcf35be70cf26e534b4767786ff8e83fTyler Gunn    }
3006f342d923df7bbb65ab801ef37bc870459396d59Sailesh Nepal}
301