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.gsm;
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.os.SystemProperties;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.PhoneNumberUtils;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.TelephonyManager;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.gsm.GsmCellLocation;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.EventLog;
30ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CallStateException;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CallTracker;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Connection;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DriverCall;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.EventLogTags;
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Phone;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.PhoneConstants;
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.TelephonyProperties;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.UUSInfo;
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.CallFailCause;
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.GSMPhone;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.GsmCall;
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.GsmConnection;
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic final class GsmCallTracker extends CallTracker {
56cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "GsmCallTracker";
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean REPEAT_POLLING = false;
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean DBG_POLL = false;
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constants
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MAX_CONNECTIONS = 7;   // only 7 connections allowed in GSM
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MAX_CONNECTIONS_PER_CALL = 5; // only 5 connections allowed per call
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Variables
6722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmConnection mConnections[] = new GsmConnection[MAX_CONNECTIONS];
6822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    RegistrantList mVoiceCallEndedRegistrants = new RegistrantList();
6922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    RegistrantList mVoiceCallStartedRegistrants = new RegistrantList();
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // connections dropped during last poll
7322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    ArrayList<GsmConnection> mDroppedDuringPoll
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        = new ArrayList<GsmConnection>(MAX_CONNECTIONS);
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCall mRingingCall = new GsmCall(this);
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // A call that is ringing or (call) waiting
7822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCall mForegroundCall = new GsmCall(this);
7922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCall mBackgroundCall = new GsmCall(this);
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
815e2000b856a7959609e8f15148a3584ec372f865Wink Saville    GsmConnection mPendingMO;
8222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    boolean mHangupPendingMO;
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GSMPhone mPhone;
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    boolean mDesiredMute = false;    // false = mute off
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    PhoneConstants.State mState = PhoneConstants.State.IDLE;
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Events
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constructors
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    GsmCallTracker (GSMPhone phone) {
9822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mPhone = phone;
9922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi = phone.mCi;
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
10422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //Unregister for all events
10922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForCallStateChanged(this);
11022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForOn(this);
11122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForNotAvailable(this);
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for(GsmConnection c : mConnections) {
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
1155e2000b856a7959609e8f15148a3584ec372f865Wink Saville                if(c != null) {
1165e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    hangup(c);
1175e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    // Since by now we are unregistered, we won't notify
1185e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    // PhoneApp that the call is gone. Do that here
1195e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    Rlog.d(LOG_TAG, "dispose: call connnection onDisconnect, cause LOST_SIGNAL");
1205e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    c.onDisconnect(Connection.DisconnectCause.LOST_SIGNAL);
1215e2000b856a7959609e8f15148a3584ec372f865Wink Saville                }
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (CallStateException ex) {
1235e2000b856a7959609e8f15148a3584ec372f865Wink Saville                Rlog.e(LOG_TAG, "dispose: unexpected error on hangup", ex);
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
1285e2000b856a7959609e8f15148a3584ec372f865Wink Saville            if(mPendingMO != null) {
1295e2000b856a7959609e8f15148a3584ec372f865Wink Saville                hangup(mPendingMO);
1305e2000b856a7959609e8f15148a3584ec372f865Wink Saville                Rlog.d(LOG_TAG, "dispose: call mPendingMO.onDsiconnect, cause LOST_SIGNAL");
1315e2000b856a7959609e8f15148a3584ec372f865Wink Saville                mPendingMO.onDisconnect(Connection.DisconnectCause.LOST_SIGNAL);
1325e2000b856a7959609e8f15148a3584ec372f865Wink Saville            }
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
1345e2000b856a7959609e8f15148a3584ec372f865Wink Saville            Rlog.e(LOG_TAG, "dispose: unexpected error on hangup", ex);
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearDisconnected();
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
142ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        Rlog.d(LOG_TAG, "GsmCallTracker finalized");
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Methods
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Public Methods
148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
15122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallStartedRegistrants.add(r);
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
154cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForVoiceCallStarted(Handler h) {
15622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallStartedRegistrants.remove(h);
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
159cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
16222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallEndedRegistrants.add(r);
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForVoiceCallEnded(Handler h) {
16722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallEndedRegistrants.remove(h);
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    fakeHoldForegroundBeforeDial() {
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List<Connection> connCopy;
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // We need to make a copy here, since fakeHoldBeforeDial()
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // modifies the lists, and we don't want to reverse the order
17622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        connCopy = (List<Connection>) mForegroundCall.mConnections.clone();
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = connCopy.size() ; i < s ; i++) {
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            GsmConnection conn = (GsmConnection)connCopy.get(i);
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            conn.fakeHoldBeforeDial();
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * clirMode is one of the CLIR_ constants
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    synchronized Connection
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException {
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // note that this triggers call state changed notif
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearDisconnected();
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!canDial()) {
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot dial in current state");
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // The new call must be assigned to the foreground call.
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // That call must be idle, so place anything that's
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // there on hold
20022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mForegroundCall.getState() == GsmCall.State.ACTIVE) {
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // this will probably be done by the radio anyway
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // but the dial might fail before this happens
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // and we need to make sure the foreground call is clear
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // for the newly dialed connection
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switchWaitingOrHoldingAndActive();
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Fake local state so that
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // a) foregroundCall is empty for the newly dialed connection
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // b) hasNonHangupStateChanged remains false in the
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // next poll, so that we don't clear a failed dialing call
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            fakeHoldForegroundBeforeDial();
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mForegroundCall.getState() != GsmCall.State.IDLE) {
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //we should have failed in !canDial() above before we get here
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot dial in current state");
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2195e2000b856a7959609e8f15148a3584ec372f865Wink Saville        mPendingMO = new GsmConnection(mPhone.getContext(), checkForTestEmergencyNumber(dialString),
22022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                this, mForegroundCall);
22122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mHangupPendingMO = false;
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2235e2000b856a7959609e8f15148a3584ec372f865Wink Saville        if (mPendingMO.mAddress == null || mPendingMO.mAddress.length() == 0
2245e2000b856a7959609e8f15148a3584ec372f865Wink Saville            || mPendingMO.mAddress.indexOf(PhoneNumberUtils.WILD) >= 0
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ) {
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Phone number is invalid
2275e2000b856a7959609e8f15148a3584ec372f865Wink Saville            mPendingMO.mCause = Connection.DisconnectCause.INVALID_NUMBER;
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // handlePollCalls() will notice this call not present
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // and will mark it as dropped.
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsWhenSafe();
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Always unmute when initiating a new call
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2365e2000b856a7959609e8f15148a3584ec372f865Wink Saville            mCi.dial(mPendingMO.mAddress, clirMode, uusInfo, obtainCompleteMessage());
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
24022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2425e2000b856a7959609e8f15148a3584ec372f865Wink Saville        return mPendingMO;
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Connection
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial(String dialString) throws CallStateException {
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return dial(dialString, CommandsInterface.CLIR_DEFAULT, null);
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Connection
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial(String dialString, UUSInfo uusInfo) throws CallStateException {
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo);
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Connection
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial(String dialString, int clirMode) throws CallStateException {
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return dial(dialString, clirMode, null);
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    acceptCall () throws CallStateException {
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // FIXME if SWITCH fails, should retry with ANSWER
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // in case the active/holding call disappeared and this
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // is no longer call waiting
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
26622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.getState() == GsmCall.State.INCOMING) {
267ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.i("phone", "acceptCall: incoming...");
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Always unmute when answering a new call
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
27022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.acceptCall(obtainCompleteMessage());
27122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mRingingCall.getState() == GsmCall.State.WAITING) {
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switchWaitingOrHoldingAndActive();
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("phone not ringing");
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    rejectCall () throws CallStateException {
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // AT+CHLD=0 means "release held or UDUB"
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so if the phone isn't ringing, this could hang up held
28322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.getState().isRinging()) {
28422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.rejectCall(obtainCompleteMessage());
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("phone not ringing");
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    switchWaitingOrHoldingAndActive() throws CallStateException {
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Should we bother with this check?
29322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.getState() == GsmCall.State.INCOMING) {
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot be in the incoming state");
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
29622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.switchWaitingOrHoldingAndActive(
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainCompleteMessage(EVENT_SWITCH_RESULT));
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    conference() {
30322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT));
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
307cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    explicitCallTransfer() {
30822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    clearDisconnected() {
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        internalClearDisconnected();
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
31622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canConference() {
32122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mForegroundCall.getState() == GsmCall.State.ACTIVE
32222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mBackgroundCall.getState() == GsmCall.State.HOLDING
32322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mBackgroundCall.isFull()
32422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mForegroundCall.isFull();
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canDial() {
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean ret;
33022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int serviceState = mPhone.getServiceState().getState();
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String disableCall = SystemProperties.get(
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret = (serviceState != ServiceState.STATE_POWER_OFF)
3355e2000b856a7959609e8f15148a3584ec372f865Wink Saville                && mPendingMO == null
33622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mRingingCall.isRinging()
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && !disableCall.equals("true")
33822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && (!mForegroundCall.getState().isAlive()
33922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    || !mBackgroundCall.getState().isAlive());
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canTransfer() {
3466eecb29d2af7d54e63a0136f97b6badad2120d23Sungmin Choi        return (mForegroundCall.getState() == GsmCall.State.ACTIVE
3476eecb29d2af7d54e63a0136f97b6badad2120d23Sungmin Choi                || mForegroundCall.getState() == GsmCall.State.ALERTING
3486eecb29d2af7d54e63a0136f97b6badad2120d23Sungmin Choi                || mForegroundCall.getState() == GsmCall.State.DIALING)
3496eecb29d2af7d54e63a0136f97b6badad2120d23Sungmin Choi            && mBackgroundCall.getState() == GsmCall.State.HOLDING;
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Private Instance Methods
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    internalClearDisconnected() {
35622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRingingCall.clearDisconnected();
35722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mForegroundCall.clearDisconnected();
35822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mBackgroundCall.clearDisconnected();
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Obtain a message to use for signalling "invoke getCurrentCalls() when
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * this operation and all other pending operations are complete
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Message
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    obtainCompleteMessage() {
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Obtain a message to use for signalling "invoke getCurrentCalls() when
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * this operation and all other pending operations are complete
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Message
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    obtainCompleteMessage(int what) {
37622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPendingOperations++;
37722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mLastRelevantPoll = null;
37822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNeedsPoll = true;
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
38122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingOperations + ", needsPoll=" + mNeedsPoll);
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return obtainMessage(what);
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    operationComplete() {
38822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPendingOperations--;
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG_POLL) log("operationComplete: pendingOperations=" +
39122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingOperations + ", needsPoll=" + mNeedsPoll);
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
39322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPendingOperations == 0 && mNeedsPoll) {
39422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
39522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.getCurrentCalls(mLastRelevantPoll);
39622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mPendingOperations < 0) {
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // this should never happen
398ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG,"GsmCallTracker.pendingOperations < 0");
39922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPendingOperations = 0;
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    updatePhoneState() {
40522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        PhoneConstants.State oldState = mState;
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
40722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.isRinging()) {
40822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.RINGING;
4095e2000b856a7959609e8f15148a3584ec372f865Wink Saville        } else if (mPendingMO != null ||
41022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                !(mForegroundCall.isIdle() && mBackgroundCall.isIdle())) {
41122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.OFFHOOK;
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
41322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.IDLE;
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
41622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState == PhoneConstants.State.IDLE && oldState != mState) {
41722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceCallEndedRegistrants.notifyRegistrants(
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                new AsyncResult(null, null, null));
41922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (oldState == PhoneConstants.State.IDLE && oldState != mState) {
42022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceCallStartedRegistrants.notifyRegistrants (
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    new AsyncResult(null, null, null));
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
42422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState != oldState) {
42522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyPhoneStateChanged();
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected synchronized void
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handlePollCalls(AsyncResult ar) {
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List polledCalls;
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception == null) {
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            polledCalls = (List)ar.result;
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // just a dummy empty ArrayList to cause the loop
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // to hang up all the calls
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            polledCalls = new ArrayList();
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Radio probably wasn't ready--try again in a bit
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // But don't keep polling if the channel is closed
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsAfterDelay();
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Connection newRinging = null; //or waiting
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasNonHangupStateChanged = false;   // Any change besides
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                    // a dropped connection
450368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        boolean hasAnyCallDisconnected = false;
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean needsPollDelay = false;
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean unknownConnectionAppeared = false;
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, curDC = 0, dcSize = polledCalls.size()
45522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                ; i < mConnections.length; i++) {
45622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            GsmConnection conn = mConnections[i];
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DriverCall dc = null;
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // polledCall list is sparse
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (curDC < dcSize) {
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = (DriverCall) polledCalls.get(curDC);
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dc.index == i+1) {
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    curDC++;
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dc = null;
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    conn+", dc=" + dc);
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn == null && dc != null) {
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Connection appeared in CLCC response that we don't know about
4755e2000b856a7959609e8f15148a3584ec372f865Wink Saville                if (mPendingMO != null && mPendingMO.compareTo(dc)) {
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4775e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    if (DBG_POLL) log("poll: pendingMO=" + mPendingMO);
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // It's our pending mobile originating call
4805e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    mConnections[i] = mPendingMO;
4815e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    mPendingMO.mIndex = i;
4825e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    mPendingMO.update(dc);
4835e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    mPendingMO = null;
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Someone has already asked to hangup this call
48622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mHangupPendingMO) {
48722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mHangupPendingMO = false;
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (Phone.DEBUG_PHONE) log(
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    "poll: hangupPendingMO, hangup conn " + i);
49122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            hangup(mConnections[i]);
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (CallStateException ex) {
493ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                            Rlog.e(LOG_TAG, "unexpected error on hangup");
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Do not continue processing this poll
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Wait for hangup and repoll
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
50122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mConnections[i] = new GsmConnection(mPhone.getContext(), dc, this, i);
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // it's a ringing call
50422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mConnections[i].getCall() == mRingingCall) {
50522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        newRinging = mConnections[i];
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Something strange happened: a call appeared
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // which is neither a ringing call or one we created.
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Either we've crashed and re-attached to an existing
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // call, or something else (eg, SIM) initiated the call.
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
512ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                        Rlog.i(LOG_TAG,"Phantom call appeared " + dc);
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // If it's a connected call, set the connect time so that
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // it's non-zero.  It may not be accurate, but at least
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // it won't appear as a Missed Call.
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (dc.state != DriverCall.State.ALERTING
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                && dc.state != DriverCall.State.DIALING) {
51922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mConnections[i].onConnectedInOrOut();
5209b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                            if (dc.state == DriverCall.State.HOLDING) {
5219b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                                // We've transitioned into HOLDING
52222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mConnections[i].onStartedHolding();
5239b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                            }
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        unknownConnectionAppeared = true;
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasNonHangupStateChanged = true;
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc == null) {
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Connection missing in CLCC response that we were
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // tracking.
53322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.add(conn);
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Dropped connections are removed from the CallTracker
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // list but kept in the GsmCall list
53622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mConnections[i] = null;
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc != null && !conn.compareTo(dc)) {
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Connection in CLCC response does not match what
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // we were tracking. Assume dropped call and new call
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
54122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.add(conn);
54222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mConnections[i] = new GsmConnection (mPhone.getContext(), dc, this, i);
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
54422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mConnections[i].getCall() == mRingingCall) {
54522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    newRinging = mConnections[i];
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } // else something strange happened
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasNonHangupStateChanged = true;
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                boolean changed;
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                changed = conn.update(dc);
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (REPEAT_POLLING) {
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dc != null) {
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // FIXME with RIL, we should not need this anymore
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((dc.state == DriverCall.State.DIALING
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.ALERTING
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.INCOMING
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.WAITING
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ) {
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Sometimes there's no unsolicited notification
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // for state transitions
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        needsPollDelay = true;
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This is the first poll after an ATD.
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // We expect the pending call to appear in the list
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If it does not, we land here
5775e2000b856a7959609e8f15148a3584ec372f865Wink Saville        if (mPendingMO != null) {
578ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.d(LOG_TAG,"Pending MO dropped before poll fg state:"
57922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            + mForegroundCall.getState());
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5815e2000b856a7959609e8f15148a3584ec372f865Wink Saville            mDroppedDuringPoll.add(mPendingMO);
5825e2000b856a7959609e8f15148a3584ec372f865Wink Saville            mPendingMO = null;
58322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mHangupPendingMO = false;
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (newRinging != null) {
58722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyNewRingingConnection(newRinging);
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // clear the "local hangup" and "missed/rejected call"
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // cases from the "dropped during poll" list
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // These cases need no "last call fail" reason
59322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = mDroppedDuringPoll.size() - 1; i >= 0 ; i--) {
59422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            GsmConnection conn = mDroppedDuringPoll.get(i);
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn.isIncoming() && conn.getConnectTime() == 0) {
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Missed or rejected call
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Connection.DisconnectCause cause;
59922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (conn.mCause == Connection.DisconnectCause.LOCAL) {
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    cause = Connection.DisconnectCause.INCOMING_REJECTED;
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    cause = Connection.DisconnectCause.INCOMING_MISSED;
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
60622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    log("missed/rejected call, conn.cause=" + conn.mCause);
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("setting cause to " + cause);
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
60922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.remove(i);
610368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann                hasAnyCallDisconnected |= conn.onDisconnect(cause);
611368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann            } else if (conn.mCause == Connection.DisconnectCause.LOCAL
612368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann                    || conn.mCause == Connection.DisconnectCause.INVALID_NUMBER) {
61322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.remove(i);
614368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann                hasAnyCallDisconnected |= conn.onDisconnect(conn.mCause);
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Any non-local disconnects: determine cause
61922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mDroppedDuringPoll.size() > 0) {
62022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.getLastCallFailCause(
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (needsPollDelay) {
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsAfterDelay();
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Cases when we can no longer keep disconnected Connection's
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // with their previous calls
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 1) the phone has started to ring
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 2) A Call/Connection object has changed state...
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //    we may have switched or held or answered (but not hung up)
633368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        if (newRinging != null || hasNonHangupStateChanged || hasAnyCallDisconnected) {
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            internalClearDisconnected();
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (unknownConnectionAppeared) {
64022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyUnknownConnection();
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
643368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        if (hasNonHangupStateChanged || newRinging != null || hasAnyCallDisconnected) {
64422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyPreciseCallStateChanged();
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //dumpState();
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleRadioNotAvailable() {
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // handlePollCalls will clear out its
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // call list when it gets the CommandException
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // error result from this
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pollCallsWhenSafe();
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dumpState() {
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List l;
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
66222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Rlog.i(LOG_TAG,"Phone State:" + mState);
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
66422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Rlog.i(LOG_TAG,"Ringing call: " + mRingingCall.toString());
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
66622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        l = mRingingCall.getConnections();
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = l.size(); i < s; i++) {
668ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.i(LOG_TAG,l.get(i).toString());
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
67122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Rlog.i(LOG_TAG,"Foreground call: " + mForegroundCall.toString());
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
67322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        l = mForegroundCall.getConnections();
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = l.size(); i < s; i++) {
675ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.i(LOG_TAG,l.get(i).toString());
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
67822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Rlog.i(LOG_TAG,"Background call: " + mBackgroundCall.toString());
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
68022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        l = mBackgroundCall.getConnections();
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = l.size(); i < s; i++) {
682ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.i(LOG_TAG,l.get(i).toString());
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from GsmConnection
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    hangup (GsmConnection conn) throws CallStateException {
69122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (conn.mOwner != this) {
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException ("GsmConnection " + conn
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    + "does not belong to GsmCallTracker " + this);
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6965e2000b856a7959609e8f15148a3584ec372f865Wink Saville        if (conn == mPendingMO) {
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // We're hanging up an outgoing call that doesn't have it's
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // GSM index assigned yet
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
70122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mHangupPendingMO = true;
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
70422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.hangupConnection (conn.getGSMIndex(), obtainCompleteMessage());
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (CallStateException ex) {
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Ignore "connection not found"
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Call may have hung up already
708ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                Rlog.w(LOG_TAG,"GsmCallTracker WARN: hangup() on absent connection "
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                + conn);
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        conn.onHangupLocal();
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    separate (GsmConnection conn) throws CallStateException {
71822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (conn.mOwner != this) {
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException ("GsmConnection " + conn
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    + "does not belong to GsmCallTracker " + this);
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
72322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.separateConnection (conn.getGSMIndex(),
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainCompleteMessage(EVENT_SEPARATE_RESULT));
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Ignore "connection not found"
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Call may have hung up already
728ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.w(LOG_TAG,"GsmCallTracker WARN: separate() on absent connection "
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                          + conn);
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from GSMPhone
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setMute(boolean mute) {
73722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mDesiredMute = mute;
73822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setMute(mDesiredMute, null);
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ boolean
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getMute() {
74322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mDesiredMute;
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from GsmCall
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */ void
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    hangup (GsmCall call) throws CallStateException {
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (call.getConnections().size() == 0) {
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("no connections in call");
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
75522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (call == mRingingCall) {
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
75722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.hangupWaitingOrBackground(obtainCompleteMessage());
75822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (call == mForegroundCall) {
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (call.isDialingOrAlerting()) {
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("(foregnd) hangup dialing or alerting...");
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangup((GsmConnection)(call.getConnections().get(0)));
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupForegroundResumeBackground();
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
76722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (call == mBackgroundCall) {
76822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mRingingCall.isRinging()) {
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("hangup all conns in background call");
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAllConnections(call);
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupWaitingOrBackground();
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new RuntimeException ("GsmCall " + call +
7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "does not belong to GsmCallTracker " + this);
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        call.onHangupLocal();
78222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupWaitingOrBackground() {
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
78822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.hangupWaitingOrBackground(obtainCompleteMessage());
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupForegroundResumeBackground() {
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
79422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.hangupForegroundResumeBackground(obtainCompleteMessage());
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupConnectionByIndex(GsmCall call, int index)
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws CallStateException {
79922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int count = call.mConnections.size();
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
80122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            GsmConnection cn = (GsmConnection)call.mConnections.get(i);
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cn.getGSMIndex() == index) {
80322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.hangupConnection(index, obtainCompleteMessage());
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        throw new CallStateException("no gsm index found");
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
811cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    void hangupAllConnections(GsmCall call) {
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
81322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            int count = call.mConnections.size();
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0; i < count; i++) {
81522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                GsmConnection cn = (GsmConnection)call.mConnections.get(i);
81622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.hangupConnection(cn.getGSMIndex(), obtainCompleteMessage());
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
819ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    GsmConnection getConnectionByIndex(GsmCall call, int index)
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws CallStateException {
82622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int count = call.mConnections.size();
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
82822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            GsmConnection cn = (GsmConnection)call.mConnections.get(i);
8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cn.getGSMIndex() == index) {
8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return cn;
8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Phone.SuppService getFailedService(int what) {
8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (what) {
8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SWITCH_RESULT:
8400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.SWITCH;
8410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CONFERENCE_RESULT:
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.CONFERENCE;
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SEPARATE_RESULT:
8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.SEPARATE;
8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_ECT_RESULT:
8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.TRANSFER;
8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return Phone.SuppService.UNKNOWN;
8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //****** Overridden from Handler
8520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
853cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage (Message msg) {
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8585e2000b856a7959609e8f15148a3584ec372f865Wink Saville        if (!mPhone.mIsTheCurrentActivePhone) {
8595e2000b856a7959609e8f15148a3584ec372f865Wink Saville            Rlog.e(LOG_TAG, "Received message " + msg +
8605e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    "[" + msg.what + "] while being destroyed. Ignoring.");
8615e2000b856a7959609e8f15148a3584ec372f865Wink Saville            return;
8625e2000b856a7959609e8f15148a3584ec372f865Wink Saville        }
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_CALLS_RESULT:
8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
86722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (msg == mLastRelevantPoll) {
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG_POLL) log(
8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
87022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNeedsPoll = false;
87122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mLastRelevantPoll = null;
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    handlePollCalls((AsyncResult)msg.obj);
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_OPERATION_COMPLETE:
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SWITCH_RESULT:
8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CONFERENCE_RESULT:
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SEPARATE_RESULT:
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_ECT_RESULT:
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception != null) {
88722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPhone.notifySuppServiceFailed(getFailedService(msg.what));
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_LAST_CALL_FAIL_CAUSE:
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int causeCode;
8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception != null) {
8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // An exception occurred...just treat the disconnect
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // cause as "normal"
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode = CallFailCause.NORMAL_CLEARING;
902ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                    Rlog.i(LOG_TAG,
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "Exception during getLastCallFailCause, assuming normal disconnect");
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode = ((int[])ar.result)[0];
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Log the causeCode if its not normal
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (causeCode == CallFailCause.NO_CIRCUIT_AVAIL ||
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.TEMPORARY_FAILURE ||
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.SWITCHING_CONGESTION ||
9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.CHANNEL_NOT_AVAIL ||
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.QOS_NOT_AVAIL ||
9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.BEARER_NOT_AVAIL ||
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.ERROR_UNSPECIFIED) {
91522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    EventLog.writeEvent(EventLogTags.CALL_DROP,
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            causeCode, loc != null ? loc.getCid() : -1,
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            TelephonyManager.getDefault().getNetworkType());
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
92122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                for (int i = 0, s =  mDroppedDuringPoll.size()
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ; i < s ; i++
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
92422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    GsmConnection conn = mDroppedDuringPoll.get(i);
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    conn.onRemoteDisconnect(causeCode);
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updatePhoneState();
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
93122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.notifyPreciseCallStateChanged();
93222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.clear();
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_REPOLL_AFTER_DELAY:
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CALL_STATE_CHANGE:
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollCallsWhenSafe();
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_AVAILABLE:
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleRadioAvailable();
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_NOT_AVAILABLE:
9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleRadioNotAvailable();
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
950cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String msg) {
952ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        Rlog.d(LOG_TAG, "[GsmCallTracker] " + msg);
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("GsmCallTracker extends:");
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
95922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println("mConnections: length=" + mConnections.length);
96022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for(int i=0; i < mConnections.length; i++) {
96122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            pw.printf("  mConnections[%d]=%s\n", i, mConnections[i]);
96222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        }
96322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mVoiceCallEndedRegistrants=" + mVoiceCallEndedRegistrants);
96422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mVoiceCallStartedRegistrants=" + mVoiceCallStartedRegistrants);
96522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDroppedDuringPoll: size=" + mDroppedDuringPoll.size());
96622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for(int i = 0; i < mDroppedDuringPoll.size(); i++) {
96722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            pw.printf( "  mDroppedDuringPoll[%d]=%s\n", i, mDroppedDuringPoll.get(i));
96822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        }
96922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mRingingCall=" + mRingingCall);
97022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mForegroundCall=" + mForegroundCall);
97122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mBackgroundCall=" + mBackgroundCall);
9725e2000b856a7959609e8f15148a3584ec372f865Wink Saville        pw.println(" mPendingMO=" + mPendingMO);
97322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mHangupPendingMO=" + mHangupPendingMO);
97422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPhone=" + mPhone);
97522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDesiredMute=" + mDesiredMute);
97622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mState=" + mState);
9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
979