10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 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
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.cdma;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.PhoneNumberUtils;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CallStateException;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CallTracker;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Connection;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DriverCall;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Phone;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.PhoneConstants;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.TelephonyProperties;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic final class CdmaCallTracker extends CallTracker {
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String LOG_TAG = "CDMA";
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean REPEAT_POLLING = false;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean DBG_POLL = false;
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constants
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MAX_CONNECTIONS = 1;   // only 1 connection allowed in CDMA
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MAX_CONNECTIONS_PER_CALL = 1; // only 1 connection allowed per call
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Variables
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CdmaConnection connections[] = new CdmaConnection[MAX_CONNECTIONS];
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    RegistrantList voiceCallEndedRegistrants = new RegistrantList();
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    RegistrantList voiceCallStartedRegistrants = new RegistrantList();
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    RegistrantList callWaitingRegistrants =  new RegistrantList();
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // connections dropped during last poll
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    ArrayList<CdmaConnection> droppedDuringPoll
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        = new ArrayList<CdmaConnection>(MAX_CONNECTIONS);
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CdmaCall ringingCall = new CdmaCall(this);
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // A call that is ringing or (call) waiting
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CdmaCall foregroundCall = new CdmaCall(this);
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CdmaCall backgroundCall = new CdmaCall(this);
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CdmaConnection pendingMO;
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean hangupPendingMO;
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean pendingCallInEcm=false;
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean mIsInEmergencyCall = false;
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CDMAPhone phone;
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean desiredMute = false;    // false = mute off
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    int pendingCallClirMode;
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    PhoneConstants.State state = PhoneConstants.State.IDLE;
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mIsEcmTimerCanceled = false;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville//    boolean needsPoll;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Events
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constructors
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CdmaCallTracker(CDMAPhone phone) {
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.phone = phone;
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm = phone.mCM;
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null);
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        foregroundCall.setGeneric(false);
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.unregisterForCallStateChanged(this);
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.unregisterForOn(this);
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.unregisterForNotAvailable(this);
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.unregisterForCallWaitingInfo(this);
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for(CdmaConnection c : connections) {
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if(c != null) hangup(c);
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (CallStateException ex) {
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Log.e(LOG_TAG, "unexpected error on hangup during dispose");
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if(pendingMO != null) hangup(pendingMO);
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.e(LOG_TAG, "unexpected error on hangup during dispose");
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearDisconnected();
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.d(LOG_TAG, "CdmaCallTracker finalized");
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Methods
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Public Methods
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        voiceCallStartedRegistrants.add(r);
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Notify if in call when registering
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (state != PhoneConstants.State.IDLE) {
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant(new AsyncResult(null, null, null));
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForVoiceCallStarted(Handler h) {
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        voiceCallStartedRegistrants.remove(h);
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        voiceCallEndedRegistrants.add(r);
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForVoiceCallEnded(Handler h) {
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        voiceCallEndedRegistrants.remove(h);
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForCallWaiting(Handler h, int what, Object obj) {
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant (h, what, obj);
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        callWaitingRegistrants.add(r);
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForCallWaiting(Handler h) {
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        callWaitingRegistrants.remove(h);
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    fakeHoldForegroundBeforeDial() {
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List<Connection> connCopy;
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // We need to make a copy here, since fakeHoldBeforeDial()
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // modifies the lists, and we don't want to reverse the order
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        connCopy = (List<Connection>) foregroundCall.connections.clone();
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = connCopy.size() ; i < s ; i++) {
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CdmaConnection conn = (CdmaConnection)connCopy.get(i);
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            conn.fakeHoldBeforeDial();
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * clirMode is one of the CLIR_ constants
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Connection
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial (String dialString, int clirMode) throws CallStateException {
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // note that this triggers call state changed notif
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearDisconnected();
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!canDial()) {
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot dial in current state");
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isPhoneInEcmMode = inEcm.equals("true");
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isEmergencyCall =
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext());
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Cancel Ecm timer if a second emergency call is originating in Ecm mode
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isPhoneInEcmMode && isEmergencyCall) {
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            handleEcmTimer(phone.CANCEL_ECM_TIMER);
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // We are initiating a call therefore even if we previously
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // didn't know the state (i.e. Generic was true) we now know
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // and therefore can set Generic to false.
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        foregroundCall.setGeneric(false);
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // The new call must be assigned to the foreground call.
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // That call must be idle, so place anything that's
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // there on hold
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (foregroundCall.getState() == CdmaCall.State.ACTIVE) {
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return dialThreeWay(dialString);
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pendingMO = new CdmaConnection(phone.getContext(), checkForTestEmergencyNumber(dialString),
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                this, foregroundCall);
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        hangupPendingMO = false;
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (pendingMO.address == null || pendingMO.address.length() == 0
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0) {
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Phone number is invalid
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // handlePollCalls() will notice this call not present
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // and will mark it as dropped.
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsWhenSafe();
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Always unmute when initiating a new call
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Check data call
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            disableDataCallInEmergencyCall(dialString);
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.exitEmergencyCallbackMode();
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pendingCallClirMode=clirMode;
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pendingCallInEcm=true;
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.notifyPreciseCallStateChanged();
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return pendingMO;
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Connection
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial (String dialString) throws CallStateException {
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return dial(dialString, CommandsInterface.CLIR_DEFAULT);
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Connection
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dialThreeWay (String dialString) {
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!foregroundCall.isIdle()) {
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Check data call
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            disableDataCallInEmergencyCall(dialString);
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Attach the new connection to foregroundCall
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pendingMO = new CdmaConnection(phone.getContext(),
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                checkForTestEmergencyNumber(dialString), this, foregroundCall);
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.sendCDMAFeatureCode(pendingMO.address,
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return pendingMO;
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    acceptCall() throws CallStateException {
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ringingCall.getState() == CdmaCall.State.INCOMING) {
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.i("phone", "acceptCall: incoming...");
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Always unmute when answering a new call
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.acceptCall(obtainCompleteMessage());
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (ringingCall.getState() == CdmaCall.State.WAITING) {
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CdmaConnection cwConn = (CdmaConnection)(ringingCall.getLatestConnection());
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Since there is no network response for supplimentary
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // service for CDMA, we assume call waiting is answered.
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // ringing Call state change to idle is in CdmaCall.detach
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // triggered by updateParent.
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cwConn.updateParent(ringingCall, foregroundCall);
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cwConn.onConnectedInOrOut();
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            updatePhoneState();
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switchWaitingOrHoldingAndActive();
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("phone not ringing");
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    rejectCall () throws CallStateException {
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // AT+CHLD=0 means "release held or UDUB"
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so if the phone isn't ringing, this could hang up held
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ringingCall.getState().isRinging()) {
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.rejectCall(obtainCompleteMessage());
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("phone not ringing");
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    switchWaitingOrHoldingAndActive() throws CallStateException {
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Should we bother with this check?
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ringingCall.getState() == CdmaCall.State.INCOMING) {
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot be in the incoming state");
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (foregroundCall.getConnections().size() > 1) {
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            flashAndSetGenericTrue();
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Send a flash command to CDMA network for putting the other party on hold.
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // For CDMA networks which do not support this the user would just hear a beep
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // from the network. For CDMA networks which do support it will put the other
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // party on hold.
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    conference() throws CallStateException {
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Should we be checking state?
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        flashAndSetGenericTrue();
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    explicitCallTransfer() throws CallStateException {
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    clearDisconnected() {
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        internalClearDisconnected();
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.notifyPreciseCallStateChanged();
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canConference() {
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return foregroundCall.getState() == CdmaCall.State.ACTIVE
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && backgroundCall.getState() == CdmaCall.State.HOLDING
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && !backgroundCall.isFull()
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && !foregroundCall.isFull();
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canDial() {
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean ret;
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int serviceState = phone.getServiceState().getState();
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String disableCall = SystemProperties.get(
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret = (serviceState != ServiceState.STATE_POWER_OFF)
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && pendingMO == null
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && !ringingCall.isRinging()
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && !disableCall.equals("true")
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && (!foregroundCall.getState().isAlive()
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    || (foregroundCall.getState() == CdmaCall.State.ACTIVE)
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    || !backgroundCall.getState().isAlive());
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!ret) {
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log(String.format("canDial is false\n" +
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "((serviceState=%d) != ServiceState.STATE_POWER_OFF)::=%s\n" +
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "&& pendingMO == null::=%s\n" +
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "&& !ringingCall.isRinging()::=%s\n" +
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "&& !disableCall.equals(\"true\")::=%s\n" +
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "&& (!foregroundCall.getState().isAlive()::=%s\n" +
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "   || foregroundCall.getState() == CdmaCall.State.ACTIVE::=%s\n" +
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "   ||!backgroundCall.getState().isAlive())::=%s)",
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    serviceState,
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    serviceState != ServiceState.STATE_POWER_OFF,
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    pendingMO == null,
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !ringingCall.isRinging(),
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !disableCall.equals("true"),
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !foregroundCall.getState().isAlive(),
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    foregroundCall.getState() == CdmaCall.State.ACTIVE,
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !backgroundCall.getState().isAlive()));
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canTransfer() {
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Private Instance Methods
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    internalClearDisconnected() {
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ringingCall.clearDisconnected();
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        foregroundCall.clearDisconnected();
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        backgroundCall.clearDisconnected();
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Obtain a message to use for signalling "invoke getCurrentCalls() when
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * this operation and all other pending operations are complete
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Message
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    obtainCompleteMessage() {
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Obtain a message to use for signalling "invoke getCurrentCalls() when
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * this operation and all other pending operations are complete
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Message
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    obtainCompleteMessage(int what) {
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pendingOperations++;
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        lastRelevantPoll = null;
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        needsPoll = true;
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pendingOperations + ", needsPoll=" + needsPoll);
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return obtainMessage(what);
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    operationComplete() {
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pendingOperations--;
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG_POLL) log("operationComplete: pendingOperations=" +
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pendingOperations + ", needsPoll=" + needsPoll);
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (pendingOperations == 0 && needsPoll) {
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.getCurrentCalls(lastRelevantPoll);
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (pendingOperations < 0) {
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // this should never happen
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.e(LOG_TAG,"CdmaCallTracker.pendingOperations < 0");
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pendingOperations = 0;
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    updatePhoneState() {
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PhoneConstants.State oldState = state;
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ringingCall.isRinging()) {
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            state = PhoneConstants.State.RINGING;
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (pendingMO != null ||
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                !(foregroundCall.isIdle() && backgroundCall.isIdle())) {
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            state = PhoneConstants.State.OFFHOOK;
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            state = PhoneConstants.State.IDLE;
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (state == PhoneConstants.State.IDLE && oldState != state) {
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            voiceCallEndedRegistrants.notifyRegistrants(
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                new AsyncResult(null, null, null));
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (oldState == PhoneConstants.State.IDLE && oldState != state) {
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            voiceCallStartedRegistrants.notifyRegistrants (
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    new AsyncResult(null, null, null));
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) {
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("update phone state, old=" + oldState + " new="+ state);
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (state != oldState) {
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.notifyPhoneStateChanged();
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // ***** Overwritten from CallTracker
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handlePollCalls(AsyncResult ar) {
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List polledCalls;
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception == null) {
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            polledCalls = (List)ar.result;
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // just a dummy empty ArrayList to cause the loop
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // to hang up all the calls
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            polledCalls = new ArrayList();
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Radio probably wasn't ready--try again in a bit
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // But don't keep polling if the channel is closed
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsAfterDelay();
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Connection newRinging = null; //or waiting
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasNonHangupStateChanged = false;   // Any change besides
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                    // a dropped connection
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean needsPollDelay = false;
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean unknownConnectionAppeared = false;
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, curDC = 0, dcSize = polledCalls.size()
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ; i < connections.length; i++) {
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CdmaConnection conn = connections[i];
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DriverCall dc = null;
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // polledCall list is sparse
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (curDC < dcSize) {
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = (DriverCall) polledCalls.get(curDC);
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dc.index == i+1) {
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    curDC++;
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dc = null;
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    conn+", dc=" + dc);
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn == null && dc != null) {
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Connection appeared in CLCC response that we don't know about
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (pendingMO != null && pendingMO.compareTo(dc)) {
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG_POLL) log("poll: pendingMO=" + pendingMO);
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // It's our pending mobile originating call
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    connections[i] = pendingMO;
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    pendingMO.index = i;
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    pendingMO.update(dc);
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    pendingMO = null;
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Someone has already asked to hangup this call
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (hangupPendingMO) {
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupPendingMO = false;
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Re-start Ecm timer when an uncompleted emergency call ends
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (mIsEcmTimerCanceled) {
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            handleEcmTimer(phone.RESTART_ECM_TIMER);
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (Phone.DEBUG_PHONE) log(
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    "poll: hangupPendingMO, hangup conn " + i);
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            hangup(connections[i]);
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (CallStateException ex) {
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            Log.e(LOG_TAG, "unexpected error on hangup");
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Do not continue processing this poll
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Wait for hangup and repoll
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (Phone.DEBUG_PHONE) {
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pendingMo=" + pendingMO + ", dc=" + dc);
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // find if the MT call is a new ring or unknown connection
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    newRinging = checkMtFindNewRinging(dc,i);
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (newRinging == null) {
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        unknownConnectionAppeared = true;
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    checkAndEnableDataCallAfterEmergencyCallDropped();
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasNonHangupStateChanged = true;
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc == null) {
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This case means the RIL has no more active call anymore and
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // we need to clean up the foregroundCall and ringingCall.
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Loop through foreground call connections as
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // it contains the known logical connections.
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int count = foregroundCall.connections.size();
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                for (int n = 0; n < count; n++) {
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (Phone.DEBUG_PHONE) log("adding fgCall cn " + n + " to droppedDuringPoll");
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n);
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    droppedDuringPoll.add(cn);
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                count = ringingCall.connections.size();
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Loop through ringing call connections as
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // it may contain the known logical connections.
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                for (int n = 0; n < count; n++) {
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (Phone.DEBUG_PHONE) log("adding rgCall cn " + n + " to droppedDuringPoll");
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CdmaConnection cn = (CdmaConnection)ringingCall.connections.get(n);
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    droppedDuringPoll.add(cn);
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                foregroundCall.setGeneric(false);
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ringingCall.setGeneric(false);
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Re-start Ecm timer when the connected emergency call ends
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (mIsEcmTimerCanceled) {
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    handleEcmTimer(phone.RESTART_ECM_TIMER);
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // If emergency call is not going through while dialing
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                checkAndEnableDataCallAfterEmergencyCallDropped();
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Dropped connections are removed from the CallTracker
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // list but kept in the Call list
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                connections[i] = null;
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Call collision case
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (conn.isIncoming != dc.isMT) {
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (dc.isMT == true){
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Mt call takes precedence than Mo,drops Mo
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        droppedDuringPoll.add(conn);
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // find if the MT call is a new ring or unknown connection
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        newRinging = checkMtFindNewRinging(dc,i);
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (newRinging == null) {
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            unknownConnectionAppeared = true;
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        checkAndEnableDataCallAfterEmergencyCallDropped();
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Call info stored in conn is not consistent with the call info from dc.
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // We should follow the rule of MT calls taking precedence over MO calls
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // when there is conflict, so here we drop the call info from dc and
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // continue to use the call info from conn, and only take a log.
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        Log.e(LOG_TAG,"Error in RIL, Phantom call appeared " + dc);
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    boolean changed;
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    changed = conn.update(dc);
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (REPEAT_POLLING) {
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dc != null) {
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // FIXME with RIL, we should not need this anymore
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((dc.state == DriverCall.State.DIALING
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.ALERTING
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.INCOMING
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.WAITING
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ) {
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Sometimes there's no unsolicited notification
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // for state transitions
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        needsPollDelay = true;
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This is the first poll after an ATD.
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // We expect the pending call to appear in the list
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If it does not, we land here
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (pendingMO != null) {
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + foregroundCall.getState());
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            droppedDuringPoll.add(pendingMO);
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pendingMO = null;
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            hangupPendingMO = false;
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if( pendingCallInEcm) {
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pendingCallInEcm = false;
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (newRinging != null) {
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.notifyNewRingingConnection(newRinging);
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // clear the "local hangup" and "missed/rejected call"
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // cases from the "dropped during poll" list
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // These cases need no "last call fail" reason
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) {
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CdmaConnection conn = droppedDuringPoll.get(i);
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn.isIncoming() && conn.getConnectTime() == 0) {
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Missed or rejected call
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Connection.DisconnectCause cause;
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (conn.cause == Connection.DisconnectCause.LOCAL) {
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    cause = Connection.DisconnectCause.INCOMING_REJECTED;
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    cause = Connection.DisconnectCause.INCOMING_MISSED;
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("missed/rejected call, conn.cause=" + conn.cause);
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("setting cause to " + cause);
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                droppedDuringPoll.remove(i);
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                conn.onDisconnect(cause);
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn.cause == Connection.DisconnectCause.LOCAL) {
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Local hangup
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                droppedDuringPoll.remove(i);
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                conn.onDisconnect(Connection.DisconnectCause.LOCAL);
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn.cause == Connection.DisconnectCause.INVALID_NUMBER) {
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                droppedDuringPoll.remove(i);
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER);
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Any non-local disconnects: determine cause
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (droppedDuringPoll.size() > 0) {
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.getLastCallFailCause(
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (needsPollDelay) {
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsAfterDelay();
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Cases when we can no longer keep disconnected Connection's
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // with their previous calls
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 1) the phone has started to ring
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 2) A Call/Connection object has changed state...
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //    we may have switched or held or answered (but not hung up)
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (newRinging != null || hasNonHangupStateChanged) {
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            internalClearDisconnected();
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (unknownConnectionAppeared) {
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.notifyUnknownConnection();
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasNonHangupStateChanged || newRinging != null) {
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.notifyPreciseCallStateChanged();
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //dumpState();
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from CdmaConnection
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    hangup (CdmaConnection conn) throws CallStateException {
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (conn.owner != this) {
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException ("CdmaConnection " + conn
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    + "does not belong to CdmaCallTracker " + this);
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (conn == pendingMO) {
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // We're hanging up an outgoing call that doesn't have it's
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // GSM index assigned yet
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            hangupPendingMO = true;
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if ((conn.getCall() == ringingCall)
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && (ringingCall.getState() == CdmaCall.State.WAITING)) {
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Handle call waiting hang up case.
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The ringingCall state will change to IDLE in CdmaCall.detach
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // if the ringing call connection size is 0. We don't specifically
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // set the ringing call state to IDLE here to avoid a race condition
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // where a new call waiting could get a hang up from an old call
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // waiting ringingCall.
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // PhoneApp does the call log itself since only PhoneApp knows
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // the hangup reason is user ignoring or timing out. So conn.onDisconnect()
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // is not called here. Instead, conn.onLocalDisconnect() is called.
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            conn.onLocalDisconnect();
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            updatePhoneState();
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.notifyPreciseCallStateChanged();
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage());
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (CallStateException ex) {
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Ignore "connection not found"
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Call may have hung up already
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Log.w(LOG_TAG,"CdmaCallTracker WARN: hangup() on absent connection "
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                + conn);
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        conn.onHangupLocal();
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    separate (CdmaConnection conn) throws CallStateException {
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (conn.owner != this) {
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException ("CdmaConnection " + conn
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    + "does not belong to CdmaCallTracker " + this);
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.separateConnection (conn.getCDMAIndex(),
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainCompleteMessage(EVENT_SEPARATE_RESULT));
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Ignore "connection not found"
7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Call may have hung up already
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.w(LOG_TAG,"CdmaCallTracker WARN: separate() on absent connection "
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                          + conn);
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from CDMAPhone
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setMute(boolean mute) {
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        desiredMute = mute;
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.setMute(desiredMute, null);
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ boolean
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getMute() {
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return desiredMute;
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from CdmaCall
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */ void
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    hangup (CdmaCall call) throws CallStateException {
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (call.getConnections().size() == 0) {
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("no connections in call");
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (call == ringingCall) {
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.hangupWaitingOrBackground(obtainCompleteMessage());
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (call == foregroundCall) {
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (call.isDialingOrAlerting()) {
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("(foregnd) hangup dialing or alerting...");
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangup((CdmaConnection)(call.getConnections().get(0)));
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupForegroundResumeBackground();
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (call == backgroundCall) {
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ringingCall.isRinging()) {
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("hangup all conns in background call");
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAllConnections(call);
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupWaitingOrBackground();
8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new RuntimeException ("CdmaCall " + call +
8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "does not belong to CdmaCallTracker " + this);
8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        call.onHangupLocal();
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.notifyPreciseCallStateChanged();
8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupWaitingOrBackground() {
8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.hangupWaitingOrBackground(obtainCompleteMessage());
8400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupForegroundResumeBackground() {
8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.hangupForegroundResumeBackground(obtainCompleteMessage());
8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupConnectionByIndex(CdmaCall call, int index)
8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws CallStateException {
8500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int count = call.connections.size();
8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
8520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CdmaConnection cn = (CdmaConnection)call.connections.get(i);
8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cn.getCDMAIndex() == index) {
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.hangupConnection(index, obtainCompleteMessage());
8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        throw new CallStateException("no gsm index found");
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupAllConnections(CdmaCall call) throws CallStateException{
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int count = call.connections.size();
8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0; i < count; i++) {
8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CdmaConnection cn = (CdmaConnection)call.connections.get(i);
8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.hangupConnection(cn.getCDMAIndex(), obtainCompleteMessage());
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CdmaConnection getConnectionByIndex(CdmaCall call, int index)
8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws CallStateException {
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int count = call.connections.size();
8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CdmaConnection cn = (CdmaConnection)call.connections.get(i);
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cn.getCDMAIndex() == index) {
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return cn;
8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void flashAndSetGenericTrue() throws CallStateException {
8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Set generic to true because in CDMA it is not known what
8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the status of the call is after a call waiting is answered,
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 3 way call merged or a switch between calls.
8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        foregroundCall.setGeneric(true);
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.notifyPreciseCallStateChanged();
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Phone.SuppService getFailedService(int what) {
8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (what) {
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SWITCH_RESULT:
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.SWITCH;
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CONFERENCE_RESULT:
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.CONFERENCE;
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SEPARATE_RESULT:
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.SEPARATE;
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_ECT_RESULT:
9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.TRANSFER;
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return Phone.SuppService.UNKNOWN;
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleRadioNotAvailable() {
9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // handlePollCalls will clear out its
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // call list when it gets the CommandException
9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // error result from this
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pollCallsWhenSafe();
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) {
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (callWaitingRegistrants != null) {
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            callWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null));
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleCallWaitingInfo (CdmaCallWaitingNotification cw) {
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Check how many connections in foregroundCall.
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If the connection in foregroundCall is more
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // than one, then the connection information is
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // not reliable anymore since it means either
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // call waiting is connected or 3 way call is
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // dialed before, so set generic.
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (foregroundCall.connections.size() > 1 ) {
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            foregroundCall.setGeneric(true);
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Create a new CdmaConnection which attaches itself to ringingCall.
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ringingCall.setGeneric(false);
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        new CdmaConnection(phone.getContext(), cw, this, ringingCall);
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Finally notify application
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyCallWaitingInfo(cw);
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //****** Overridden from Handler
9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage (Message msg) {
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_CALLS_RESULT:{
9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Log.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if(msg == lastRelevantPoll) {
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if(DBG_POLL) log(
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    needsPoll = false;
9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    lastRelevantPoll = null;
9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    handlePollCalls((AsyncResult)msg.obj);
9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_OPERATION_COMPLETE:
9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SWITCH_RESULT:
9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 // In GSM call operationComplete() here which gets the
9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 // current call list. But in CDMA there is no list so
9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 // there is nothing to do.
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_LAST_CALL_FAIL_CAUSE:
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int causeCode;
9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception != null) {
9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // An exception occurred...just treat the disconnect
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // cause as "normal"
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode = CallFailCause.NORMAL_CLEARING;
9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Log.i(LOG_TAG,
9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "Exception during getLastCallFailCause, assuming normal disconnect");
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode = ((int[])ar.result)[0];
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                for (int i = 0, s =  droppedDuringPoll.size()
9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ; i < s ; i++
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CdmaConnection conn = droppedDuringPoll.get(i);
9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    conn.onRemoteDisconnect(causeCode);
9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updatePhoneState();
10000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.notifyPreciseCallStateChanged();
10020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                droppedDuringPoll.clear();
10030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_REPOLL_AFTER_DELAY:
10060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CALL_STATE_CHANGE:
10070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollCallsWhenSafe();
10080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_AVAILABLE:
10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleRadioAvailable();
10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_NOT_AVAILABLE:
10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleRadioNotAvailable();
10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_EXIT_ECM_RESPONSE_CDMA:
10190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               //no matter the result, we still do the same here
10200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               if (pendingCallInEcm) {
10210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                   cm.dial(pendingMO.address, pendingCallClirMode, obtainCompleteMessage());
10220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                   pendingCallInEcm = false;
10230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               }
10240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               phone.unsetOnEcbModeExitResponse(this);
10250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CALL_WAITING_INFO_CDMA:
10280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               ar = (AsyncResult)msg.obj;
10290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               if (ar.exception == null) {
10300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                   handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result);
10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                   Log.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received");
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               }
10330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA:
10360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
10370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Assume 3 way call is connected
10390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    pendingMO.onConnectedInOrOut();
10400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    pendingMO = null;
10410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:{
10450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               throw new RuntimeException("unexpected event not handled");
10460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handle Ecm timer to be canceled or re-started
10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleEcmTimer(int action) {
10540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.handleTimerInEmergencyCallbackMode(action);
10550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch(action) {
10560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CDMAPhone.CANCEL_ECM_TIMER: mIsEcmTimerCanceled = true; break;
10570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CDMAPhone.RESTART_ECM_TIMER: mIsEcmTimerCanceled = false; break;
10580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        default:
10590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.e(LOG_TAG, "handleEcmTimer, unsupported action " + action);
10600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Disable data call when emergency call is connected
10650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void disableDataCallInEmergencyCall(String dialString) {
10670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) {
10680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("disableDataCallInEmergencyCall");
10690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mIsInEmergencyCall = true;
10700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.mDataConnectionTracker.setInternalDataEnabled(false);
10710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check and enable data call after an emergency call is dropped if it's
10760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * not in ECM
10770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void checkAndEnableDataCallAfterEmergencyCallDropped() {
10790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mIsInEmergencyCall) {
10800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mIsInEmergencyCall = false;
10810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
10820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) {
10830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("checkAndEnableDataCallAfterEmergencyCallDropped,inEcm=" + inEcm);
10840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (inEcm.compareTo("false") == 0) {
10860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Re-initiate data connection
10870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.mDataConnectionTracker.setInternalDataEnabled(true);
10880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check the MT call to see if it's a new ring or
10940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * a unknown connection.
10950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Connection checkMtFindNewRinging(DriverCall dc, int i) {
10970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Connection newRinging = null;
10990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        connections[i] = new CdmaConnection(phone.getContext(), dc, this, i);
11010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // it's a ringing call
11020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (connections[i].getCall() == ringingCall) {
11030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            newRinging = connections[i];
11040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("Notify new ring " + dc);
11050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
11060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Something strange happened: a call which is neither
11070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // a ringing call nor the one we created. It could be the
11080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // call collision result from RIL
11090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.e(LOG_TAG,"Phantom call appeared " + dc);
11100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // If it's a connected call, set the connect time so that
11110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // it's non-zero.  It may not be accurate, but at least
11120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // it won't appear as a Missed Call.
11130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dc.state != DriverCall.State.ALERTING
11140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && dc.state != DriverCall.State.DIALING) {
11150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                connections[i].connectTime = System.currentTimeMillis();
11160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return newRinging;
11190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if current call is in emergency call
11230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
11240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if it is in emergency call
11250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         false if it is not in emergency call
11260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean isInEmergencyCall() {
11280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mIsInEmergencyCall;
11290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String msg) {
11320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.d(LOG_TAG, "[CdmaCallTracker] " + msg);
11330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
11360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("GsmCallTracker extends:");
11380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
11390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("droppedDuringPoll: length=" + connections.length);
11400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for(int i=0; i < connections.length; i++) {
11410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pw.printf(" connections[%d]=%s\n", i, connections[i]);
11420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" voiceCallEndedRegistrants=" + voiceCallEndedRegistrants);
11440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" voiceCallStartedRegistrants=" + voiceCallStartedRegistrants);
11450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" callWaitingRegistrants=" + callWaitingRegistrants);
11460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("droppedDuringPoll: size=" + droppedDuringPoll.size());
11470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for(int i = 0; i < droppedDuringPoll.size(); i++) {
11480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pw.printf( " droppedDuringPoll[%d]=%s\n", i, droppedDuringPoll.get(i));
11490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" ringingCall=" + ringingCall);
11510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" foregroundCall=" + foregroundCall);
11520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" backgroundCall=" + backgroundCall);
11530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" pendingMO=" + pendingMO);
11540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" hangupPendingMO=" + hangupPendingMO);
11550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" pendingCallInEcm=" + pendingCallInEcm);
11560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mIsInEmergencyCall=" + mIsInEmergencyCall);
11570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" phone=" + phone);
11580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" desiredMute=" + desiredMute);
11590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" pendingCallClirMode=" + pendingCallClirMode);
11600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" state=" + state);
11610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mIsEcmTimerCanceled=" + mIsEcmTimerCanceled);
11620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1164