10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
21a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu * Copyright (C) 2015 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yupackage com.android.internal.telephony;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.content.BroadcastReceiver;
20e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wuimport android.content.Context;
211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.content.Intent;
221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.content.IntentFilter;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.os.Bundle;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.os.SystemProperties;
301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.telephony.CellLocation;
31b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensenimport android.telephony.DisconnectCause;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.PhoneNumberUtils;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
34e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wuimport android.telephony.TelephonyManager;
351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.telephony.cdma.CdmaCellLocation;
361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.telephony.gsm.GsmCellLocation;
372d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Yingimport android.text.TextUtils;
381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.Iterator;
391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.telephony.Rlog;
401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.util.EventLog;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.telephony.EventLogTags;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport java.util.ArrayList;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yupublic class GsmCdmaCallTracker extends CallTracker {
5432b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private static final String LOG_TAG = "GsmCdmaCallTracker";
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean REPEAT_POLLING = false;
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean DBG_POLL = false;
581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private static final boolean VDBG = false;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constants
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6232b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public static final int MAX_CONNECTIONS_GSM = 19;   //7 allowed in GSM + 12 from IMS for SRVCC
6332b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private static final int MAX_CONNECTIONS_PER_CALL_GSM = 5; //only 5 connections allowed per call
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6532b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private static final int MAX_CONNECTIONS_CDMA = 8;
6632b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private static final int MAX_CONNECTIONS_PER_CALL_CDMA = 1; //only 1 connection allowed per call
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //***** Instance Variables
6932b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private GsmCdmaConnection mConnections[];
7032b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private RegistrantList mVoiceCallEndedRegistrants = new RegistrantList();
7132b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private RegistrantList mVoiceCallStartedRegistrants = new RegistrantList();
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // connections dropped during last poll
7432b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private ArrayList<GsmCdmaConnection> mDroppedDuringPoll =
7532b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan            new ArrayList<GsmCdmaConnection>(MAX_CONNECTIONS_GSM);
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public GsmCdmaCall mRingingCall = new GsmCdmaCall(this);
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // A call that is ringing or (call) waiting
791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public GsmCdmaCall mForegroundCall = new GsmCdmaCall(this);
801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public GsmCdmaCall mBackgroundCall = new GsmCdmaCall(this);
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8232b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private GsmCdmaConnection mPendingMO;
8332b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private boolean mHangupPendingMO;
841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
850a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private GsmCdmaPhone mPhone;
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8732b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private boolean mDesiredMute = false;    // false = mute off
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public PhoneConstants.State mState = PhoneConstants.State.IDLE;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
919746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak    private TelephonyEventLog mEventLog;
929746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak
931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    // Following member variables are for CDMA only
9432b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private RegistrantList mCallWaitingRegistrants = new RegistrantList();
9532b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private boolean mPendingCallInEcm;
9632b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private boolean mIsInEmergencyCall;
9732b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private int mPendingCallClirMode;
981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean mIsEcmTimerCanceled;
991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private int m3WayCallFlashDelay;
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
1021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Listens for Emergency Callback Mode state change intents
1031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
1041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private BroadcastReceiver mEcmExitReceiver = new BroadcastReceiver() {
1051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        @Override
1061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        public void onReceive(Context context, Intent intent) {
1071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (intent.getAction().equals(
1081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
1091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                boolean isInEcm = intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, false);
1111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("Received ACTION_EMERGENCY_CALLBACK_MODE_CHANGED isInEcm = " + isInEcm);
1121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // If we exit ECM mode, notify all connections.
1141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!isInEcm) {
1151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Although mConnections seems to be the place to look, it is not guaranteed
1161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // to have all of the connections we're tracking.  THe best place to look is in
1171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // the Call objects associated with the tracker.
1181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    List<Connection> toNotify = new ArrayList<Connection>();
1191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    toNotify.addAll(mRingingCall.getConnections());
1201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    toNotify.addAll(mForegroundCall.getConnections());
1211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    toNotify.addAll(mBackgroundCall.getConnections());
1221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mPendingMO != null) {
1231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        toNotify.add(mPendingMO);
1241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Notify connections that ECM mode exited.
1271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    for (Connection connection : toNotify) {
1281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (connection != null) {
1291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            connection.onExitedEcmMode();
1301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
1311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
1321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
1331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
1341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
1351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    };
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Events
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constructors
1411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
14232b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public GsmCdmaCallTracker (GsmCdmaPhone phone) {
1431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        this.mPhone = phone;
14422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi = phone.mCi;
14522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
14622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
14722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
1485c1251a7bd7dceba6203722f0bf0fb6062732da2Amit Mahajan
1495c1251a7bd7dceba6203722f0bf0fb6062732da2Amit Mahajan        // Register receiver for ECM exit
1505c1251a7bd7dceba6203722f0bf0fb6062732da2Amit Mahajan        IntentFilter filter = new IntentFilter();
1515c1251a7bd7dceba6203722f0bf0fb6062732da2Amit Mahajan        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
1525c1251a7bd7dceba6203722f0bf0fb6062732da2Amit Mahajan        mPhone.getContext().registerReceiver(mEcmExitReceiver, filter);
1535c1251a7bd7dceba6203722f0bf0fb6062732da2Amit Mahajan
154ce86f3f624c6a8fd2c58e93a7b76989b3eaa8208Amit Mahajan        updatePhoneType(true);
1559746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak
1567a1c1b02c8603c2bf2f3b401facb389528180eedPavel Zhamaitsiak        mEventLog = new TelephonyEventLog(mPhone.getPhoneId());
1571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
1581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1590a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    public void updatePhoneType() {
160ce86f3f624c6a8fd2c58e93a7b76989b3eaa8208Amit Mahajan        updatePhoneType(false);
161ce86f3f624c6a8fd2c58e93a7b76989b3eaa8208Amit Mahajan    }
162ce86f3f624c6a8fd2c58e93a7b76989b3eaa8208Amit Mahajan
163ebbb6b76ebb0afd9e66f5927f431a93f0f0b85b7Amit Mahajan    private void updatePhoneType(boolean duringInit) {
164ebbb6b76ebb0afd9e66f5927f431a93f0f0b85b7Amit Mahajan        if (!duringInit) {
165ce86f3f624c6a8fd2c58e93a7b76989b3eaa8208Amit Mahajan            reset();
166ebbb6b76ebb0afd9e66f5927f431a93f0f0b85b7Amit Mahajan            pollCallsWhenSafe();
167ce86f3f624c6a8fd2c58e93a7b76989b3eaa8208Amit Mahajan        }
1681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mPhone.isPhoneTypeGsm()) {
1691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mConnections = new GsmCdmaConnection[MAX_CONNECTIONS_GSM];
1705f6ea8a0105a163b801b82f1af22174f855086f4Amit Mahajan            mCi.unregisterForCallWaitingInfo(this);
1711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
1721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mConnections = new GsmCdmaConnection[MAX_CONNECTIONS_CDMA];
1731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPendingCallInEcm = false;
1741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mIsInEmergencyCall = false;
1751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPendingCallClirMode = CommandsInterface.CLIR_DEFAULT;
1761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mIsEcmTimerCanceled = false;
1771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            m3WayCallFlashDelay = 0;
1781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mCi.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null);
1791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
182ce86f3f624c6a8fd2c58e93a7b76989b3eaa8208Amit Mahajan    private void reset() {
183ce86f3f624c6a8fd2c58e93a7b76989b3eaa8208Amit Mahajan        Rlog.d(LOG_TAG, "reset");
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearDisconnected();
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (GsmCdmaConnection gsmCdmaConnection : mConnections) {
1881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (gsmCdmaConnection != null) {
1891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                gsmCdmaConnection.dispose();
1908f811769f344f892056e17eb81c8d74a457cf133Amit Mahajan            }
1918f811769f344f892056e17eb81c8d74a457cf133Amit Mahajan        }
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
1961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Rlog.d(LOG_TAG, "GsmCdmaCallTracker finalized");
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Methods
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Public Methods
202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
20522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallStartedRegistrants.add(r);
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Notify if in call when registering
20722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState != PhoneConstants.State.IDLE) {
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant(new AsyncResult(null, null, null));
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForVoiceCallStarted(Handler h) {
21422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallStartedRegistrants.remove(h);
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
217cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
22022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallEndedRegistrants.add(r);
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
223cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForVoiceCallEnded(Handler h) {
22522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallEndedRegistrants.remove(h);
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForCallWaiting(Handler h, int what, Object obj) {
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant (h, what, obj);
23022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCallWaitingRegistrants.add(r);
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForCallWaiting(Handler h) {
23422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCallWaitingRegistrants.remove(h);
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23732b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private void fakeHoldForegroundBeforeDial() {
2381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        List<Connection> connCopy;
2391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // We need to make a copy here, since fakeHoldBeforeDial()
2411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // modifies the lists, and we don't want to reverse the order
2421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        connCopy = (List<Connection>) mForegroundCall.mConnections.clone();
2431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (int i = 0, s = connCopy.size() ; i < s ; i++) {
2451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            GsmCdmaConnection conn = (GsmCdmaConnection)connCopy.get(i);
2461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            conn.fakeHoldBeforeDial();
2481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
2501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //GSM
2521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
2531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * clirMode is one of the CLIR_ constants
2541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
25532b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public synchronized Connection dial(String dialString, int clirMode, UUSInfo uusInfo,
25632b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan                                        Bundle intentExtras)
2571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            throws CallStateException {
2581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // note that this triggers call state changed notif
2591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        clearDisconnected();
2601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!canDial()) {
2621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            throw new CallStateException("cannot dial in current state");
2631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        String origNumber = dialString;
2661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        dialString = convertNumberIfNecessary(mPhone, dialString);
2671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // The new call must be assigned to the foreground call.
2691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // That call must be idle, so place anything that's
2701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // there on hold
2711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mForegroundCall.getState() == GsmCdmaCall.State.ACTIVE) {
2721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // this will probably be done by the radio anyway
2731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // but the dial might fail before this happens
2741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // and we need to make sure the foreground call is clear
2751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // for the newly dialed connection
2761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            switchWaitingOrHoldingAndActive();
2771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // This is a hack to delay DIAL so that it is sent out to RIL only after
2781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // EVENT_SWITCH_RESULT is received. We've seen failures when adding a new call to
2791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // multi-way conference calls due to DIAL being sent out before SWITCH is processed
2801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            try {
2811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Thread.sleep(500);
2821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } catch (InterruptedException e) {
2831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // do nothing
2841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Fake local state so that
2871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // a) foregroundCall is empty for the newly dialed connection
2881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // b) hasNonHangupStateChanged remains false in the
2891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // next poll, so that we don't clear a failed dialing call
2901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            fakeHoldForegroundBeforeDial();
2911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mForegroundCall.getState() != GsmCdmaCall.State.IDLE) {
2941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            //we should have failed in !canDial() above before we get here
2951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            throw new CallStateException("cannot dial in current state");
2961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPendingMO = new GsmCdmaConnection(mPhone, checkForTestEmergencyNumber(dialString),
2991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                this, mForegroundCall);
3001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mHangupPendingMO = false;
3011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if ( mPendingMO.getAddress() == null || mPendingMO.getAddress().length() == 0
3031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                || mPendingMO.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0) {
3041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Phone number is invalid
3051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPendingMO.mCause = DisconnectCause.INVALID_NUMBER;
3061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // handlePollCalls() will notice this call not present
3081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // and will mark it as dropped.
3091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pollCallsWhenSafe();
3101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
3111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Always unmute when initiating a new call
3121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            setMute(false);
3131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mCi.dial(mPendingMO.getAddress(), clirMode, uusInfo, obtainCompleteMessage());
3151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mNumberConverted) {
3181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPendingMO.setConverted(origNumber);
3191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mNumberConverted = false;
3201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        updatePhoneState();
3231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.notifyPreciseCallStateChanged();
3241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mPendingMO;
3261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
3271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //CDMA
3291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
3301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Handle Ecm timer to be canceled or re-started
3311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
3321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void handleEcmTimer(int action) {
3331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.handleTimerInEmergencyCallbackMode(action);
3341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        switch(action) {
3351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case GsmCdmaPhone.CANCEL_ECM_TIMER: mIsEcmTimerCanceled = true; break;
3361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case GsmCdmaPhone.RESTART_ECM_TIMER: mIsEcmTimerCanceled = false; break;
3371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            default:
3381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Rlog.e(LOG_TAG, "handleEcmTimer, unsupported action " + action);
3391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
3411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //CDMA
3431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    /**
3441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     * Disable data call when emergency call is connected
3451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu     */
3461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void disableDataCallInEmergencyCall(String dialString) {
3471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (PhoneNumberUtils.isLocalEmergencyNumber(mPhone.getContext(), dialString)) {
3481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (Phone.DEBUG_PHONE) log("disableDataCallInEmergencyCall");
3491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            setIsInEmergencyCall();
3501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
3511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
3521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //CDMA
35432b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void setIsInEmergencyCall() {
3551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mIsInEmergencyCall = true;
3561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.mDcTracker.setInternalDataEnabled(false);
3571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.notifyEmergencyCallRegistrants(true);
358a579e9c631d70bb6dbd39283438212d5ff8f19c0Amit Mahajan        mPhone.sendEmergencyCallStateChange(true);
3591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
3601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
3611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //CDMA
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * clirMode is one of the CLIR_ constants
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
36532b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private Connection dial(String dialString, int clirMode) throws CallStateException {
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // note that this triggers call state changed notif
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearDisconnected();
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!canDial()) {
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot dial in current state");
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
373e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu        TelephonyManager tm =
374e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                (TelephonyManager) mPhone.getContext().getSystemService(Context.TELEPHONY_SERVICE);
3752d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        String origNumber = dialString;
376e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu        String operatorIsoContry = tm.getNetworkCountryIsoForPhone(mPhone.getPhoneId());
377e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu        String simIsoContry = tm.getSimCountryIsoForPhone(mPhone.getPhoneId());
3782d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        boolean internationalRoaming = !TextUtils.isEmpty(operatorIsoContry)
3792d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying                && !TextUtils.isEmpty(simIsoContry)
3802d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying                && !simIsoContry.equals(operatorIsoContry);
3812d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        if (internationalRoaming) {
3822d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            if ("us".equals(simIsoContry)) {
3832d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying                internationalRoaming = internationalRoaming && !"vi".equals(operatorIsoContry);
3842d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            } else if ("vi".equals(simIsoContry)) {
3852d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying                internationalRoaming = internationalRoaming && !"us".equals(operatorIsoContry);
3862d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            }
3872d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        }
3882d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        if (internationalRoaming) {
3892d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            dialString = convertNumberIfNecessary(mPhone, dialString);
3902d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        }
3912d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isPhoneInEcmMode = inEcm.equals("true");
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isEmergencyCall =
395f4f5308a309d43fcfca8d0d5fbb54bc38c82ca3fYorke Lee                PhoneNumberUtils.isLocalEmergencyNumber(mPhone.getContext(), dialString);
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Cancel Ecm timer if a second emergency call is originating in Ecm mode
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isPhoneInEcmMode && isEmergencyCall) {
3991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            handleEcmTimer(GsmCdmaPhone.CANCEL_ECM_TIMER);
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // The new call must be assigned to the foreground call.
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // That call must be idle, so place anything that's
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // there on hold
4051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mForegroundCall.getState() == GsmCdmaCall.State.ACTIVE) {
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return dialThreeWay(dialString);
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPendingMO = new GsmCdmaConnection(mPhone, checkForTestEmergencyNumber(dialString),
41022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                this, mForegroundCall);
41122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mHangupPendingMO = false;
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
413e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam        if ( mPendingMO.getAddress() == null || mPendingMO.getAddress().length() == 0
414e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                || mPendingMO.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0 ) {
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Phone number is invalid
416b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen            mPendingMO.mCause = DisconnectCause.INVALID_NUMBER;
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // handlePollCalls() will notice this call not present
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // and will mark it as dropped.
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsWhenSafe();
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Always unmute when initiating a new call
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Check data call
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            disableDataCallInEmergencyCall(dialString);
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
430e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                mCi.dial(mPendingMO.getAddress(), clirMode, obtainCompleteMessage());
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
43222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.exitEmergencyCallbackMode();
43322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
43422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingCallClirMode=clirMode;
43522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingCallInEcm=true;
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4392d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        if (mNumberConverted) {
4402d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            mPendingMO.setConverted(origNumber);
4412d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            mNumberConverted = false;
4422d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        }
4432d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
44522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
44722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mPendingMO;
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //CDMA
45132b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private Connection dialThreeWay(String dialString) {
45222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mForegroundCall.isIdle()) {
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Check data call
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            disableDataCallInEmergencyCall(dialString);
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Attach the new connection to foregroundCall
4571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mPendingMO = new GsmCdmaConnection(mPhone,
4581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    checkForTestEmergencyNumber(dialString), this, mForegroundCall);
459bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            // Some network need a empty flash before sending the normal one
460bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            m3WayCallFlashDelay = mPhone.getContext().getResources()
461bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                    .getInteger(com.android.internal.R.integer.config_cdma_3waycall_flash_delay);
462bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            if (m3WayCallFlashDelay > 0) {
463bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                mCi.sendCDMAFeatureCode("", obtainMessage(EVENT_THREE_WAY_DIAL_BLANK_FLASH));
464bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            } else {
465bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                mCi.sendCDMAFeatureCode(mPendingMO.getAddress(),
466bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                        obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
467bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            }
46822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return mPendingMO;
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
47332b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public Connection dial(String dialString) throws CallStateException {
4741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (isPhoneTypeGsm()) {
4751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return dial(dialString, CommandsInterface.CLIR_DEFAULT, null);
4761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
4771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return dial(dialString, CommandsInterface.CLIR_DEFAULT);
4781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
4791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //GSM
48232b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public Connection dial(String dialString, UUSInfo uusInfo, Bundle intentExtras)
48332b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan            throws CallStateException {
4841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo, intentExtras);
4851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //GSM
48832b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private Connection dial(String dialString, int clirMode, Bundle intentExtras)
48932b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan            throws CallStateException {
4901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return dial(dialString, clirMode, null, intentExtras);
4911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
4921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
49332b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void acceptCall() throws CallStateException {
4941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // FIXME if SWITCH fails, should retry with ANSWER
4951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // in case the active/holding call disappeared and this
4961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // is no longer call waiting
4971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
4981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mRingingCall.getState() == GsmCdmaCall.State.INCOMING) {
499ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.i("phone", "acceptCall: incoming...");
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Always unmute when answering a new call
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
50222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.acceptCall(obtainCompleteMessage());
5031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (mRingingCall.getState() == GsmCdmaCall.State.WAITING) {
5041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (isPhoneTypeGsm()) {
5051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                setMute(false);
5061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
5071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                GsmCdmaConnection cwConn = (GsmCdmaConnection)(mRingingCall.getLatestConnection());
5081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // Since there is no network response for supplimentary
5101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // service for CDMA, we assume call waiting is answered.
5111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // ringing Call state change to idle is in GsmCdmaCall.detach
5121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // triggered by updateParent.
5131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cwConn.updateParent(mRingingCall, mForegroundCall);
5141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                cwConn.onConnectedInOrOut();
5151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                updatePhoneState();
5161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switchWaitingOrHoldingAndActive();
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("phone not ringing");
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
52332b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void rejectCall() throws CallStateException {
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // AT+CHLD=0 means "release held or UDUB"
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so if the phone isn't ringing, this could hang up held
52622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.getState().isRinging()) {
52722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.rejectCall(obtainCompleteMessage());
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("phone not ringing");
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //CDMA
5341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private void flashAndSetGenericTrue() {
5351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mCi.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
5361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
5371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        mPhone.notifyPreciseCallStateChanged();
5381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
5391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
54032b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void switchWaitingOrHoldingAndActive() throws CallStateException {
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Should we bother with this check?
5421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (mRingingCall.getState() == GsmCdmaCall.State.INCOMING) {
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot be in the incoming state");
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
5451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (isPhoneTypeGsm()) {
5461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mCi.switchWaitingOrHoldingAndActive(
5471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        obtainCompleteMessage(EVENT_SWITCH_RESULT));
5481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
5491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (mForegroundCall.getConnections().size() > 1) {
5501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    flashAndSetGenericTrue();
5511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
5521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Send a flash command to CDMA network for putting the other party on hold.
5531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // For CDMA networks which do not support this the user would just hear a beep
5541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // from the network. For CDMA networks which do support it will put the other
5551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // party on hold.
5561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mCi.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
5571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
5581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
56232b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void conference() {
5631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (isPhoneTypeGsm()) {
5641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mCi.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT));
5651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
5661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // Should we be checking state?
5671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            flashAndSetGenericTrue();
5681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
57132b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void explicitCallTransfer() {
57222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
57532b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void clearDisconnected() {
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        internalClearDisconnected();
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
57922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
58232b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public boolean canConference() {
5831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mForegroundCall.getState() == GsmCdmaCall.State.ACTIVE
5841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                && mBackgroundCall.getState() == GsmCdmaCall.State.HOLDING
58522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mBackgroundCall.isFull()
58622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mForegroundCall.isFull();
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
58932b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private boolean canDial() {
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean ret;
59122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int serviceState = mPhone.getServiceState().getState();
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String disableCall = SystemProperties.get(
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret = (serviceState != ServiceState.STATE_POWER_OFF)
59622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mPendingMO == null
59722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mRingingCall.isRinging()
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && !disableCall.equals("true")
59922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && (!mForegroundCall.getState().isAlive()
6001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || !mBackgroundCall.getState().isAlive()
6011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || (!isPhoneTypeGsm()
6021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        && mForegroundCall.getState() == GsmCdmaCall.State.ACTIVE));
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!ret) {
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log(String.format("canDial is false\n" +
6061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "((serviceState=%d) != ServiceState.STATE_POWER_OFF)::=%s\n" +
6071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "&& pendingMO == null::=%s\n" +
6081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "&& !ringingCall.isRinging()::=%s\n" +
6091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "&& !disableCall.equals(\"true\")::=%s\n" +
6101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "&& (!foregroundCall.getState().isAlive()::=%s\n" +
6111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "   || foregroundCall.getState() == GsmCdmaCall.State.ACTIVE::=%s\n" +
6121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "   ||!backgroundCall.getState().isAlive())::=%s)",
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    serviceState,
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    serviceState != ServiceState.STATE_POWER_OFF,
61522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingMO == null,
61622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    !mRingingCall.isRinging(),
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !disableCall.equals("true"),
61822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    !mForegroundCall.getState().isAlive(),
6191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mForegroundCall.getState() == GsmCdmaCall.State.ACTIVE,
62022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    !mBackgroundCall.getState().isAlive()));
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
62632b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public boolean canTransfer() {
6271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (isPhoneTypeGsm()) {
6281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return (mForegroundCall.getState() == GsmCdmaCall.State.ACTIVE
6291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || mForegroundCall.getState() == GsmCdmaCall.State.ALERTING
6301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    || mForegroundCall.getState() == GsmCdmaCall.State.DIALING)
6311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    && mBackgroundCall.getState() == GsmCdmaCall.State.HOLDING;
6321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else {
6331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Rlog.e(LOG_TAG, "canTransfer: not possible in CDMA");
6341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            return false;
6351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Private Instance Methods
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
64032b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private void internalClearDisconnected() {
64122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRingingCall.clearDisconnected();
64222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mForegroundCall.clearDisconnected();
64322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mBackgroundCall.clearDisconnected();
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Obtain a message to use for signalling "invoke getCurrentCalls() when
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * this operation and all other pending operations are complete
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
65032b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private Message obtainCompleteMessage() {
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Obtain a message to use for signalling "invoke getCurrentCalls() when
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * this operation and all other pending operations are complete
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
65832b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private Message obtainCompleteMessage(int what) {
65922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPendingOperations++;
66022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mLastRelevantPoll = null;
66122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNeedsPoll = true;
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
66422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingOperations + ", needsPoll=" + mNeedsPoll);
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return obtainMessage(what);
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
66932b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private void operationComplete() {
67022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPendingOperations--;
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG_POLL) log("operationComplete: pendingOperations=" +
67322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingOperations + ", needsPoll=" + mNeedsPoll);
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
67522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPendingOperations == 0 && mNeedsPoll) {
67622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
67722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.getCurrentCalls(mLastRelevantPoll);
67822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mPendingOperations < 0) {
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // this should never happen
6801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Rlog.e(LOG_TAG,"GsmCdmaCallTracker.pendingOperations < 0");
68122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPendingOperations = 0;
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
68532b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private void updatePhoneState() {
68622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        PhoneConstants.State oldState = mState;
68722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.isRinging()) {
68822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.RINGING;
68922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mPendingMO != null ||
69022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                !(mForegroundCall.isIdle() && mBackgroundCall.isIdle())) {
69122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.OFFHOOK;
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
693c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan            Phone imsPhone = mPhone.getImsPhone();
69469e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            if ( mState == PhoneConstants.State.OFFHOOK && (imsPhone != null)){
69569e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com                imsPhone.callEndCleanupHandOverCallIfAny();
69669e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            }
69722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.IDLE;
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
70022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState == PhoneConstants.State.IDLE && oldState != mState) {
70122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceCallEndedRegistrants.notifyRegistrants(
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                new AsyncResult(null, null, null));
70322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (oldState == PhoneConstants.State.IDLE && oldState != mState) {
70422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceCallStartedRegistrants.notifyRegistrants (
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    new AsyncResult(null, null, null));
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) {
70822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            log("update phone state, old=" + oldState + " new="+ mState);
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
71022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState != oldState) {
71122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyPhoneStateChanged();
7129746fca2d7389f0fce6d5d031d87acd87b9de723Pavel Zhamaitsiak            mEventLog.writePhoneState(mState);
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // ***** Overwritten from CallTracker
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
718cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
71932b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    protected synchronized void handlePollCalls(AsyncResult ar) {
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List polledCalls;
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("handlePollCalls");
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception == null) {
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            polledCalls = (List)ar.result;
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // just a dummy empty ArrayList to cause the loop
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // to hang up all the calls
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            polledCalls = new ArrayList();
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Radio probably wasn't ready--try again in a bit
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // But don't keep polling if the channel is closed
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsAfterDelay();
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Connection newRinging = null; //or waiting
7371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        ArrayList<Connection> newUnknownConnectionsGsm = new ArrayList<Connection>();
7381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Connection newUnknownConnectionCdma = null;
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasNonHangupStateChanged = false;   // Any change besides
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                    // a dropped connection
741368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        boolean hasAnyCallDisconnected = false;
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean needsPollDelay = false;
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean unknownConnectionAppeared = false;
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        //CDMA
7468bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan        boolean noConnectionExists = true;
7478bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, curDC = 0, dcSize = polledCalls.size()
74922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                ; i < mConnections.length; i++) {
7501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            GsmCdmaConnection conn = mConnections[i];
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DriverCall dc = null;
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // polledCall list is sparse
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (curDC < dcSize) {
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = (DriverCall) polledCalls.get(curDC);
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dc.index == i+1) {
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    curDC++;
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dc = null;
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            //CDMA
7658bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan            if (conn != null || dc != null) {
7668bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan                noConnectionExists = false;
7678bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan            }
7688bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    conn+", dc=" + dc);
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn == null && dc != null) {
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Connection appeared in CLCC response that we don't know about
77422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mPendingMO != null && mPendingMO.compareTo(dc)) {
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
77622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (DBG_POLL) log("poll: pendingMO=" + mPendingMO);
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // It's our pending mobile originating call
77922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mConnections[i] = mPendingMO;
78022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingMO.mIndex = i;
78122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingMO.update(dc);
78222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingMO = null;
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Someone has already asked to hangup this call
78522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mHangupPendingMO) {
78622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mHangupPendingMO = false;
7871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Re-start Ecm timer when an uncompleted emergency call ends
7891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (!isPhoneTypeGsm() && mIsEcmTimerCanceled) {
7901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            handleEcmTimer(GsmCdmaPhone.RESTART_ECM_TIMER);
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (Phone.DEBUG_PHONE) log(
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    "poll: hangupPendingMO, hangup conn " + i);
79622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            hangup(mConnections[i]);
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (CallStateException ex) {
798ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                            Rlog.e(LOG_TAG, "unexpected error on hangup");
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Do not continue processing this poll
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Wait for hangup and repoll
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (Phone.DEBUG_PHONE) {
80722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        log("pendingMo=" + mPendingMO + ", dc=" + dc);
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
8091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mConnections[i] = new GsmCdmaConnection(mPhone, dc, this, i);
811e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam
8124be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                    Connection hoConnection = getHoConnection(dc);
8134be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                    if (hoConnection != null) {
814e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        // Single Radio Voice Call Continuity (SRVCC) completed
8154be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                        mConnections[i].migrateFrom(hoConnection);
81608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        // Updating connect time for silent redial cases (ex: Calls are transferred
81708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        // from DIALING/ALERTING/INCOMING/WAITING to ACTIVE)
8181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (hoConnection.mPreHandoverState != GsmCdmaCall.State.ACTIVE &&
819a374c57705a7a9ff7ffa89f1d220fa4be3bc5897Shriram Ganesh                                hoConnection.mPreHandoverState != GsmCdmaCall.State.HOLDING &&
820a374c57705a7a9ff7ffa89f1d220fa4be3bc5897Shriram Ganesh                                dc.state == DriverCall.State.ACTIVE) {
82108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                            mConnections[i].onConnectedInOrOut();
82208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        }
82308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
8244be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                        mHandoverConnections.remove(hoConnection);
8251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (isPhoneTypeGsm()) {
8271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            for (Iterator<Connection> it = mHandoverConnections.iterator();
8281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                 it.hasNext(); ) {
8291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                Connection c = it.next();
8301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                Rlog.i(LOG_TAG, "HO Conn state is " + c.mPreHandoverState);
8311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                if (c.mPreHandoverState == mConnections[i].getState()) {
8321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    Rlog.i(LOG_TAG, "Removing HO conn "
8331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                            + hoConnection + c.mPreHandoverState);
8341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    it.remove();
8351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                }
8361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            }
8371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
8381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
839e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        mPhone.notifyHandoverStateChanged(mConnections[i]);
840e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                    } else {
841e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        // find if the MT call is a new ring or unknown connection
842e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        newRinging = checkMtFindNewRinging(dc,i);
843e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        if (newRinging == null) {
844e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                            unknownConnectionAppeared = true;
8451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            if (isPhoneTypeGsm()) {
8461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                newUnknownConnectionsGsm.add(mConnections[i]);
8471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            } else {
8481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                newUnknownConnectionCdma = mConnections[i];
8491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            }
850e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        }
8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
8520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasNonHangupStateChanged = true;
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc == null) {
8551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (isPhoneTypeGsm()) {
8561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Connection missing in CLCC response that we were
8571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // tracking.
8581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mDroppedDuringPoll.add(conn);
8591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Dropped connections are removed from the CallTracker
8601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // list but kept in the GsmCdmaCall list
8611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mConnections[i] = null;
8621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
8631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // This case means the RIL has no more active call anymore and
8641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // we need to clean up the foregroundCall and ringingCall.
8651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Loop through foreground call connections as
8661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // it contains the known logical connections.
8671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int count = mForegroundCall.mConnections.size();
8681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    for (int n = 0; n < count; n++) {
8691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (Phone.DEBUG_PHONE) log("adding fgCall cn " + n + " to droppedDuringPoll");
8701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        GsmCdmaConnection cn = (GsmCdmaConnection)mForegroundCall.mConnections.get(n);
8711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mDroppedDuringPoll.add(cn);
8721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
8731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    count = mRingingCall.mConnections.size();
8741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Loop through ringing call connections as
8751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // it may contain the known logical connections.
8761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    for (int n = 0; n < count; n++) {
8771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (Phone.DEBUG_PHONE) log("adding rgCall cn " + n + " to droppedDuringPoll");
8781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        GsmCdmaConnection cn = (GsmCdmaConnection)mRingingCall.mConnections.get(n);
8791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mDroppedDuringPoll.add(cn);
8801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
8811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Re-start Ecm timer when the connected emergency call ends
8831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mIsEcmTimerCanceled) {
8841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        handleEcmTimer(GsmCdmaPhone.RESTART_ECM_TIMER);
8851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
8861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // If emergency call is not going through while dialing
8871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    checkAndEnableDataCallAfterEmergencyCallDropped();
8881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // Dropped connections are removed from the CallTracker
8901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // list but kept in the Call list
8911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mConnections[i] = null;
8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (conn != null && dc != null && !conn.compareTo(dc) && isPhoneTypeGsm()) {
8951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // Connection in CLCC response does not match what
8961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // we were tracking. Assume dropped call and new call
8971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
8981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mDroppedDuringPoll.add(conn);
8991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mConnections[i] = new GsmCdmaConnection (mPhone, dc, this, i);
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (mConnections[i].getCall() == mRingingCall) {
9021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    newRinging = mConnections[i];
9031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } // else something strange happened
9041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                hasNonHangupStateChanged = true;
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Call collision case
9071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!isPhoneTypeGsm() && conn.isIncoming() != dc.isMT) {
9081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (dc.isMT == true) {
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Mt call takes precedence than Mo,drops Mo
91022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mDroppedDuringPoll.add(conn);
9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // find if the MT call is a new ring or unknown connection
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        newRinging = checkMtFindNewRinging(dc,i);
9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (newRinging == null) {
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            unknownConnectionAppeared = true;
9151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            newUnknownConnectionCdma = conn;
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        checkAndEnableDataCallAfterEmergencyCallDropped();
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Call info stored in conn is not consistent with the call info from dc.
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // We should follow the rule of MT calls taking precedence over MO calls
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // when there is conflict, so here we drop the call info from dc and
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // continue to use the call info from conn, and only take a log.
923ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                        Rlog.e(LOG_TAG,"Error in RIL, Phantom call appeared " + dc);
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    boolean changed;
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    changed = conn.update(dc);
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (REPEAT_POLLING) {
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dc != null) {
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // FIXME with RIL, we should not need this anymore
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((dc.state == DriverCall.State.DIALING
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.ALERTING
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.INCOMING
9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.WAITING
9421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)) {
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Sometimes there's no unsolicited notification
9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // for state transitions
9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        needsPollDelay = true;
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9518bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan        // Safety check so that obj is not stuck with mIsInEmergencyCall set to true (and data
9528bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan        // disabled). This should never happen though.
9531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!isPhoneTypeGsm() && noConnectionExists) {
9548bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan            checkAndEnableDataCallAfterEmergencyCallDropped();
9558bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan        }
9568bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This is the first poll after an ATD.
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // We expect the pending call to appear in the list
9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If it does not, we land here
96022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPendingMO != null) {
9611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Rlog.d(LOG_TAG, "Pending MO dropped before poll fg state:"
9621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    + mForegroundCall.getState());
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
96422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mDroppedDuringPoll.add(mPendingMO);
96522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPendingMO = null;
96622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mHangupPendingMO = false;
9671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
9681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (!isPhoneTypeGsm()) {
9691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if( mPendingCallInEcm) {
9701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mPendingCallInEcm = false;
9711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
9721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                checkAndEnableDataCallAfterEmergencyCallDropped();
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (newRinging != null) {
97722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyNewRingingConnection(newRinging);
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // clear the "local hangup" and "missed/rejected call"
9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // cases from the "dropped during poll" list
9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // These cases need no "last call fail" reason
98322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = mDroppedDuringPoll.size() - 1; i >= 0 ; i--) {
9841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            GsmCdmaConnection conn = mDroppedDuringPoll.get(i);
9851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            //CDMA
986f77612abdb6de211f33d5b3598d269b291c1d4a8Santos Cordon            boolean wasDisconnected = false;
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn.isIncoming() && conn.getConnectTime() == 0) {
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Missed or rejected call
990b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                int cause;
991b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                if (conn.mCause == DisconnectCause.LOCAL) {
992b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                    cause = DisconnectCause.INCOMING_REJECTED;
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
994b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                    cause = DisconnectCause.INCOMING_MISSED;
9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
99822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    log("missed/rejected call, conn.cause=" + conn.mCause);
9990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("setting cause to " + cause);
10000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
100122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.remove(i);
1002368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann                hasAnyCallDisconnected |= conn.onDisconnect(cause);
1003f77612abdb6de211f33d5b3598d269b291c1d4a8Santos Cordon                wasDisconnected = true;
1004b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen            } else if (conn.mCause == DisconnectCause.LOCAL
1005b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                    || conn.mCause == DisconnectCause.INVALID_NUMBER) {
100622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.remove(i);
1007368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann                hasAnyCallDisconnected |= conn.onDisconnect(conn.mCause);
1008f77612abdb6de211f33d5b3598d269b291c1d4a8Santos Cordon                wasDisconnected = true;
1009f77612abdb6de211f33d5b3598d269b291c1d4a8Santos Cordon            }
1010f77612abdb6de211f33d5b3598d269b291c1d4a8Santos Cordon
10111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (!isPhoneTypeGsm() && wasDisconnected && unknownConnectionAppeared
10121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    && conn == newUnknownConnectionCdma) {
1013f77612abdb6de211f33d5b3598d269b291c1d4a8Santos Cordon                unknownConnectionAppeared = false;
10141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                newUnknownConnectionCdma = null;
10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1018de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade        /* Disconnect any pending Handover connections */
1019ab759cc92562162ceeb3d1a5b7592b704185433dShriram Ganesh        for (Iterator<Connection> it = mHandoverConnections.iterator();
1020ab759cc92562162ceeb3d1a5b7592b704185433dShriram Ganesh                it.hasNext();) {
1021ab759cc92562162ceeb3d1a5b7592b704185433dShriram Ganesh            Connection hoConnection = it.next();
1022e12a56f2331dc49271b50c8ca12c0c17e324a187Shriram Ganesh            log("handlePollCalls - disconnect hoConn= " + hoConnection +
1023e12a56f2331dc49271b50c8ca12c0c17e324a187Shriram Ganesh                    " hoConn.State= " + hoConnection.getState());
1024e12a56f2331dc49271b50c8ca12c0c17e324a187Shriram Ganesh            if (hoConnection.getState().isRinging()) {
1025e12a56f2331dc49271b50c8ca12c0c17e324a187Shriram Ganesh                hoConnection.onDisconnect(DisconnectCause.INCOMING_MISSED);
1026e12a56f2331dc49271b50c8ca12c0c17e324a187Shriram Ganesh            } else {
1027e12a56f2331dc49271b50c8ca12c0c17e324a187Shriram Ganesh                hoConnection.onDisconnect(DisconnectCause.NOT_VALID);
1028e12a56f2331dc49271b50c8ca12c0c17e324a187Shriram Ganesh            }
1029ab759cc92562162ceeb3d1a5b7592b704185433dShriram Ganesh            it.remove();
1030de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade        }
1031de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Any non-local disconnects: determine cause
103322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mDroppedDuringPoll.size() > 0) {
103422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.getLastCallFailCause(
10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
10360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (needsPollDelay) {
10390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsAfterDelay();
10400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Cases when we can no longer keep disconnected Connection's
10430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // with their previous calls
10440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 1) the phone has started to ring
10450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 2) A Call/Connection object has changed state...
10460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //    we may have switched or held or answered (but not hung up)
1047368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        if (newRinging != null || hasNonHangupStateChanged || hasAnyCallDisconnected) {
10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            internalClearDisconnected();
10490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (VDBG) log("handlePollCalls calling updatePhoneState()");
10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (unknownConnectionAppeared) {
10551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (isPhoneTypeGsm()) {
10561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                for (Connection c : newUnknownConnectionsGsm) {
10571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    log("Notify unknown for " + c);
10581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mPhone.notifyUnknownConnection(c);
10591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
10601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else {
10611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mPhone.notifyUnknownConnection(newUnknownConnectionCdma);
10621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1065368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        if (hasNonHangupStateChanged || newRinging != null || hasAnyCallDisconnected) {
106622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyPreciseCallStateChanged();
10670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //dumpState();
10700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
107232b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private void handleRadioNotAvailable() {
10731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // handlePollCalls will clear out its
10741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // call list when it gets the CommandException
10751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // error result from this
10761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pollCallsWhenSafe();
10771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
10781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
107932b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private void dumpState() {
10801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        List l;
10811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
10821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Rlog.i(LOG_TAG,"Phone State:" + mState);
10831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
10841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Rlog.i(LOG_TAG,"Ringing call: " + mRingingCall.toString());
10851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
10861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        l = mRingingCall.getConnections();
10871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (int i = 0, s = l.size(); i < s; i++) {
10881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Rlog.i(LOG_TAG,l.get(i).toString());
10891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
10901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
10911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Rlog.i(LOG_TAG,"Foreground call: " + mForegroundCall.toString());
10921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
10931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        l = mForegroundCall.getConnections();
10941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (int i = 0, s = l.size(); i < s; i++) {
10951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Rlog.i(LOG_TAG,l.get(i).toString());
10961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
10971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
10981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Rlog.i(LOG_TAG,"Background call: " + mBackgroundCall.toString());
10991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
11001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        l = mBackgroundCall.getConnections();
11011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        for (int i = 0, s = l.size(); i < s; i++) {
11021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Rlog.i(LOG_TAG,l.get(i).toString());
11031a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
11041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
11051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
11061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
11071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //***** Called from GsmCdmaConnection
11081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
110932b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void hangup(GsmCdmaConnection conn) throws CallStateException {
111022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (conn.mOwner != this) {
11111a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            throw new CallStateException ("GsmCdmaConnection " + conn
11121a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + "does not belong to GsmCdmaCallTracker " + this);
11130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
111522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (conn == mPendingMO) {
11160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // We're hanging up an outgoing call that doesn't have it's
11171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // GsmCdma index assigned yet
11180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
112022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mHangupPendingMO = true;
11211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        } else if (!isPhoneTypeGsm()
11221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                && conn.getCall() == mRingingCall
11231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                && mRingingCall.getState() == GsmCdmaCall.State.WAITING) {
11240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Handle call waiting hang up case.
11250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
11261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            // The ringingCall state will change to IDLE in GsmCdmaCall.detach
11270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // if the ringing call connection size is 0. We don't specifically
11280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // set the ringing call state to IDLE here to avoid a race condition
11290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // where a new call waiting could get a hang up from an old call
11300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // waiting ringingCall.
11310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
11320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // PhoneApp does the call log itself since only PhoneApp knows
11330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // the hangup reason is user ignoring or timing out. So conn.onDisconnect()
11340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // is not called here. Instead, conn.onLocalDisconnect() is called.
11350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            conn.onLocalDisconnect();
11361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
11370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            updatePhoneState();
113822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyPreciseCallStateChanged();
11390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
11400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
11410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
11421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mCi.hangupConnection (conn.getGsmCdmaIndex(), obtainCompleteMessage());
11430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (CallStateException ex) {
11440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Ignore "connection not found"
11450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Call may have hung up already
11461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                Rlog.w(LOG_TAG,"GsmCdmaCallTracker WARN: hangup() on absent connection "
11470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                + conn);
11480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        conn.onHangupLocal();
11520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
115432b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void separate(GsmCdmaConnection conn) throws CallStateException {
115522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (conn.mOwner != this) {
11561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            throw new CallStateException ("GsmCdmaConnection " + conn
11571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    + "does not belong to GsmCdmaCallTracker " + this);
11580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
11601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mCi.separateConnection (conn.getGsmCdmaIndex(),
11610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainCompleteMessage(EVENT_SEPARATE_RESULT));
11620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
11630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Ignore "connection not found"
11640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Call may have hung up already
11651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Rlog.w(LOG_TAG,"GsmCdmaCallTracker WARN: separate() on absent connection " + conn);
11660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //***** Called from GsmCdmaPhone
11700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
117132b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void setMute(boolean mute) {
117222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mDesiredMute = mute;
117322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setMute(mDesiredMute, null);
11740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
117632b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public boolean getMute() {
117722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mDesiredMute;
11780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //***** Called from GsmCdmaCall
11820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
118332b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void hangup(GsmCdmaCall call) throws CallStateException {
11840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (call.getConnections().size() == 0) {
11850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("no connections in call");
11860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
118822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (call == mRingingCall) {
11890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
119022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.hangupWaitingOrBackground(obtainCompleteMessage());
119122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (call == mForegroundCall) {
11920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (call.isDialingOrAlerting()) {
11930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
11940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("(foregnd) hangup dialing or alerting...");
11950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
11961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                hangup((GsmCdmaConnection)(call.getConnections().get(0)));
11971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            } else if (isPhoneTypeGsm()
11981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    && mRingingCall.isRinging()) {
11991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // Do not auto-answer ringing on CHUP, instead just end active calls
12001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                log("hangup all conns in active/background call, without affecting ringing call");
12011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                hangupAllConnections(call);
12020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
12030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupForegroundResumeBackground();
12040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
120522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (call == mBackgroundCall) {
120622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mRingingCall.isRinging()) {
12070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
12080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("hangup all conns in background call");
12090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAllConnections(call);
12110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
12120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupWaitingOrBackground();
12130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
12151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            throw new RuntimeException ("GsmCdmaCall " + call +
12161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    "does not belong to GsmCdmaCallTracker " + this);
12170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        call.onHangupLocal();
122022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
12210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
122332b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void hangupWaitingOrBackground() {
12240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
122522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.hangupWaitingOrBackground(obtainCompleteMessage());
12260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
122832b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void hangupForegroundResumeBackground() {
12290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
123022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.hangupForegroundResumeBackground(obtainCompleteMessage());
12310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
123332b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void hangupConnectionByIndex(GsmCdmaCall call, int index)
12340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws CallStateException {
123522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int count = call.mConnections.size();
12360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
12371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            GsmCdmaConnection cn = (GsmCdmaConnection)call.mConnections.get(i);
12381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (cn.getGsmCdmaIndex() == index) {
123922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.hangupConnection(index, obtainCompleteMessage());
12400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
12410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        throw new CallStateException("no GsmCdma index found");
12450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
124732b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void hangupAllConnections(GsmCdmaCall call) {
12480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
124922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            int count = call.mConnections.size();
12500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0; i < count; i++) {
12511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                GsmCdmaConnection cn = (GsmCdmaConnection)call.mConnections.get(i);
12521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                mCi.hangupConnection(cn.getGsmCdmaIndex(), obtainCompleteMessage());
12530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
1255ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
12560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
125932b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public GsmCdmaConnection getConnectionByIndex(GsmCdmaCall call, int index)
12600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws CallStateException {
126122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int count = call.mConnections.size();
12620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
12631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            GsmCdmaConnection cn = (GsmCdmaConnection)call.mConnections.get(i);
12641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (cn.getGsmCdmaIndex() == index) {
12650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return cn;
12660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
12700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //CDMA
12730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) {
127422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCallWaitingRegistrants != null) {
127522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCallWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null));
12760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //CDMA
128032b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    private void handleCallWaitingInfo(CdmaCallWaitingNotification cw) {
12811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        // Create a new GsmCdmaConnection which attaches itself to ringingCall.
12821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        new GsmCdmaConnection(mPhone.getContext(), cw, this, mRingingCall);
12830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
12840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Finally notify application
12860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyCallWaitingInfo(cw);
12870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
12891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private Phone.SuppService getFailedService(int what) {
12901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        switch (what) {
12911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case EVENT_SWITCH_RESULT:
12921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                return Phone.SuppService.SWITCH;
12931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case EVENT_CONFERENCE_RESULT:
12941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                return Phone.SuppService.CONFERENCE;
12951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case EVENT_SEPARATE_RESULT:
12961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                return Phone.SuppService.SEPARATE;
12971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case EVENT_ECT_RESULT:
12981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                return Phone.SuppService.TRANSFER;
12991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
13001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return Phone.SuppService.UNKNOWN;
13011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
13021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
13030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //****** Overridden from Handler
13040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1305cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
130632b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public void handleMessage(Message msg) {
13070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
13080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
13101a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case EVENT_POLL_CALLS_RESULT:
1311ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
13120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (msg == mLastRelevantPoll) {
13141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (DBG_POLL) log(
13150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
131622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNeedsPoll = false;
131722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mLastRelevantPoll = null;
13180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    handlePollCalls((AsyncResult)msg.obj);
13190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
13200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
13210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_OPERATION_COMPLETE:
13230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
13240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
13250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case EVENT_CONFERENCE_RESULT:
13271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (isPhoneTypeGsm()) {
13281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // The conference merge failed, so notify listeners.  Ultimately this bubbles up
13291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // to Telecom, which will inform the InCall UI of the failure.
13301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    Connection connection = mForegroundCall.getLatestConnection();
13311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (connection != null) {
13321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        connection.onConferenceMergeFailed();
13331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
13341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
13351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // fall through
13361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case EVENT_SEPARATE_RESULT:
13371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            case EVENT_ECT_RESULT:
13380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SWITCH_RESULT:
13391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (isPhoneTypeGsm()) {
13401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    ar = (AsyncResult) msg.obj;
13411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (ar.exception != null) {
13421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mPhone.notifySuppServiceFailed(getFailedService(msg.what));
13431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
13441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    operationComplete();
13451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
13461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (msg.what != EVENT_SWITCH_RESULT) {
13471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        // EVENT_SWITCH_RESULT in GSM call triggers operationComplete() which gets
13481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        // the current call list. But in CDMA there is no list so there is nothing
13491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        // to do. Other messages however are not expected in CDMA.
13501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        throw new RuntimeException("unexpected event " + msg.what + " not handled by " +
13511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                "phone type " + mPhone.getPhoneType());
13521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
13531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
13540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
13550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_LAST_CALL_FAIL_CAUSE:
13570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int causeCode;
135833cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu                String vendorCause = null;
13590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
13600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
13620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception != null) {
13640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // An exception occurred...just treat the disconnect
13650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // cause as "normal"
13660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode = CallFailCause.NORMAL_CLEARING;
1367ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                    Rlog.i(LOG_TAG,
13680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "Exception during getLastCallFailCause, assuming normal disconnect");
13690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
137033cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu                    LastCallFailCause failCause = (LastCallFailCause)ar.result;
137133cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu                    causeCode = failCause.causeCode;
137233cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu                    vendorCause = failCause.vendorCause;
13730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
13741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                // Log the causeCode if its not normal
13751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (causeCode == CallFailCause.NO_CIRCUIT_AVAIL ||
13761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    causeCode == CallFailCause.TEMPORARY_FAILURE ||
13771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    causeCode == CallFailCause.SWITCHING_CONGESTION ||
13781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    causeCode == CallFailCause.CHANNEL_NOT_AVAIL ||
13791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    causeCode == CallFailCause.QOS_NOT_AVAIL ||
13801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    causeCode == CallFailCause.BEARER_NOT_AVAIL ||
13811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    causeCode == CallFailCause.ERROR_UNSPECIFIED) {
13821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
13831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    CellLocation loc = mPhone.getCellLocation();
13841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    int cid = -1;
13851a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (loc != null) {
13861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        if (isPhoneTypeGsm()) {
13871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            cid = ((GsmCellLocation)loc).getCid();
13881a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        } else {
13891a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            cid = ((CdmaCellLocation)loc).getBaseStationId();
13901a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        }
13911a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
13921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    EventLog.writeEvent(EventLogTags.CALL_DROP, causeCode, cid,
13931a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            TelephonyManager.getDefault().getNetworkType());
13941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
13950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                for (int i = 0, s = mDroppedDuringPoll.size(); i < s ; i++) {
13971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    GsmCdmaConnection conn = mDroppedDuringPoll.get(i);
13980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
139933cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu                    conn.onRemoteDisconnect(causeCode, vendorCause);
14000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updatePhoneState();
14030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
140422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.notifyPreciseCallStateChanged();
140522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.clear();
14060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
14070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_REPOLL_AFTER_DELAY:
14090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CALL_STATE_CHANGE:
14100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollCallsWhenSafe();
14110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
14120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_AVAILABLE:
14140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleRadioAvailable();
14150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
14160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_NOT_AVAILABLE:
14180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleRadioNotAvailable();
14190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
14200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_EXIT_ECM_RESPONSE_CDMA:
14221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!isPhoneTypeGsm()) {
14231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    // no matter the result, we still do the same here
14241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (mPendingCallInEcm) {
14251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mCi.dial(mPendingMO.getAddress(), mPendingCallClirMode, obtainCompleteMessage());
14261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mPendingCallInEcm = false;
14271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
14281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    mPhone.unsetOnEcbModeExitResponse(this);
14291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
14301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    throw new RuntimeException("unexpected event " + msg.what + " not handled by " +
14311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "phone type " + mPhone.getPhoneType());
1432e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                }
14331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
14340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CALL_WAITING_INFO_CDMA:
14361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!isPhoneTypeGsm()) {
14371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    ar = (AsyncResult)msg.obj;
14381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (ar.exception == null) {
14391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result);
14401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Rlog.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received");
14411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
14421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
14431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    throw new RuntimeException("unexpected event " + msg.what + " not handled by " +
14441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "phone type " + mPhone.getPhoneType());
14451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                }
14461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
14470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA:
14491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!isPhoneTypeGsm()) {
14501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    ar = (AsyncResult)msg.obj;
14511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (ar.exception == null) {
14521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        // Assume 3 way call is connected
14531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mPendingMO.onConnectedInOrOut();
14541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mPendingMO = null;
14551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
14561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                } else {
14571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    throw new RuntimeException("unexpected event " + msg.what + " not handled by " +
14581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "phone type " + mPhone.getPhoneType());
14590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
14610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1462bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            case EVENT_THREE_WAY_DIAL_BLANK_FLASH:
14631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                if (!isPhoneTypeGsm()) {
14641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    ar = (AsyncResult) msg.obj;
14651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    if (ar.exception == null) {
14661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        postDelayed(
14671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                new Runnable() {
14681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                    public void run() {
14691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                        if (mPendingMO != null) {
14701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                            mCi.sendCDMAFeatureCode(mPendingMO.getAddress(),
14711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                                    obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
14721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                        }
1473bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                                    }
14741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                                }, m3WayCallFlashDelay);
14751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    } else {
14761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        mPendingMO = null;
14771a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        Rlog.w(LOG_TAG, "exception happened on Blank Flash for 3-way call");
14781a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    }
1479bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                } else {
14801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    throw new RuntimeException("unexpected event " + msg.what + " not handled by " +
14811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                            "phone type " + mPhone.getPhoneType());
1482bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                }
14831a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                break;
1484bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao
14850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:{
14861a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                throw new RuntimeException("unexpected event " + msg.what + " not handled by " +
14871a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                        "phone type " + mPhone.getPhoneType());
14880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14921a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //CDMA
14930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check and enable data call after an emergency call is dropped if it's
14950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * not in ECM
14960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void checkAndEnableDataCallAfterEmergencyCallDropped() {
14980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mIsInEmergencyCall) {
14990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mIsInEmergencyCall = false;
15000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
15010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) {
15020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("checkAndEnableDataCallAfterEmergencyCallDropped,inEcm=" + inEcm);
15030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (inEcm.compareTo("false") == 0) {
15050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Re-initiate data connection
1506454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville                mPhone.mDcTracker.setInternalDataEnabled(true);
1507f3cb9192272e4ddd68970352e998690f6c80e393Amit Mahajan                mPhone.notifyEmergencyCallRegistrants(false);
15080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1509a579e9c631d70bb6dbd39283438212d5ff8f19c0Amit Mahajan            mPhone.sendEmergencyCallStateChange(false);
15100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check the MT call to see if it's a new ring or
15150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * a unknown connection.
15160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Connection checkMtFindNewRinging(DriverCall dc, int i) {
15180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Connection newRinging = null;
15200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // it's a ringing call
152222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mConnections[i].getCall() == mRingingCall) {
152322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            newRinging = mConnections[i];
15240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("Notify new ring " + dc);
15250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
15260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Something strange happened: a call which is neither
15270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // a ringing call nor the one we created. It could be the
15280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // call collision result from RIL
1529ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG,"Phantom call appeared " + dc);
15300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // If it's a connected call, set the connect time so that
15310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // it's non-zero.  It may not be accurate, but at least
15320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // it won't appear as a Missed Call.
15330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dc.state != DriverCall.State.ALERTING
15341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                    && dc.state != DriverCall.State.DIALING) {
153522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mConnections[i].onConnectedInOrOut();
15369b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                if (dc.state == DriverCall.State.HOLDING) {
15379b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                    // We've transitioned into HOLDING
153822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mConnections[i].onStartedHolding();
15399b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                }
15400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return newRinging;
15430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    //CDMA
15460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if current call is in emergency call
15480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if it is in emergency call
15500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         false if it is not in emergency call
15510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
155232b5fbb1a340fa16e2c37c276517ef10a4934500Amit Mahajan    public boolean isInEmergencyCall() {
15530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mIsInEmergencyCall;
15540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    private boolean isPhoneTypeGsm() {
15571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM;
15581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
15591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
15600a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    public GsmCdmaPhone getPhone() {
15610a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        return mPhone;
15620a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    }
15630a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
1564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
15650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String msg) {
15661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Rlog.d(LOG_TAG, "[GsmCdmaCallTracker] " + msg);
15670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
15700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println("GsmCdmaCallTracker extends:");
15720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
15731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println("mConnections: length=" + mConnections.length);
157422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for(int i=0; i < mConnections.length; i++) {
15751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.printf("  mConnections[%d]=%s\n", i, mConnections[i]);
15760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
157722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mVoiceCallEndedRegistrants=" + mVoiceCallEndedRegistrants);
157822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mVoiceCallStartedRegistrants=" + mVoiceCallStartedRegistrants);
15791a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!isPhoneTypeGsm()) {
15801a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mCallWaitingRegistrants=" + mCallWaitingRegistrants);
15811a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
15821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        pw.println(" mDroppedDuringPoll: size=" + mDroppedDuringPoll.size());
158322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for(int i = 0; i < mDroppedDuringPoll.size(); i++) {
15841a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.printf( "  mDroppedDuringPoll[%d]=%s\n", i, mDroppedDuringPoll.get(i));
15850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
158622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mRingingCall=" + mRingingCall);
158722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mForegroundCall=" + mForegroundCall);
158822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mBackgroundCall=" + mBackgroundCall);
158922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPendingMO=" + mPendingMO);
159022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mHangupPendingMO=" + mHangupPendingMO);
159122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPhone=" + mPhone);
159222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDesiredMute=" + mDesiredMute);
159322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mState=" + mState);
15941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (!isPhoneTypeGsm()) {
15951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mPendingCallInEcm=" + mPendingCallInEcm);
15961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mIsInEmergencyCall=" + mIsInEmergencyCall);
15971a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mPendingCallClirMode=" + mPendingCallClirMode);
15981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            pw.println(" mIsEcmTimerCanceled=" + mIsEcmTimerCanceled);
15991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
16001a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
16010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16020a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
1603b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    @Override
1604b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    public PhoneConstants.State getState() {
1605b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        return mState;
1606b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    }
1607dd4b0f4b5a2def03bd45637be5ceed3e86781f68Amit Mahajan
1608dd4b0f4b5a2def03bd45637be5ceed3e86781f68Amit Mahajan    public int getMaxConnectionsPerCall() {
1609dd4b0f4b5a2def03bd45637be5ceed3e86781f68Amit Mahajan        return mPhone.isPhoneTypeGsm() ?
1610dd4b0f4b5a2def03bd45637be5ceed3e86781f68Amit Mahajan                MAX_CONNECTIONS_PER_CALL_GSM :
1611dd4b0f4b5a2def03bd45637be5ceed3e86781f68Amit Mahajan                MAX_CONNECTIONS_PER_CALL_CDMA;
1612dd4b0f4b5a2def03bd45637be5ceed3e86781f68Amit Mahajan    }
16130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1614