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;
25b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensenimport android.telephony.DisconnectCause;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.PhoneNumberUtils;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.TelephonyManager;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.gsm.GsmCellLocation;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.EventLog;
31ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
33a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Call;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CallStateException;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CallTracker;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Connection;
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DriverCall;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.EventLogTags;
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Phone;
41e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingamimport com.android.internal.telephony.PhoneBase;
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.PhoneConstants;
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.TelephonyProperties;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.UUSInfo;
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.CallFailCause;
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.GSMPhone;
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.GsmCall;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.GsmConnection;
4969e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.comimport com.android.internal.telephony.imsphone.ImsPhone;
50de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangadeimport com.android.internal.telephony.imsphone.ImsPhoneConnection;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic final class GsmCallTracker extends CallTracker {
61cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "GsmCallTracker";
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean REPEAT_POLLING = false;
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean DBG_POLL = false;
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constants
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MAX_CONNECTIONS = 7;   // only 7 connections allowed in GSM
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MAX_CONNECTIONS_PER_CALL = 5; // only 5 connections allowed per call
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Variables
7222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmConnection mConnections[] = new GsmConnection[MAX_CONNECTIONS];
7322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    RegistrantList mVoiceCallEndedRegistrants = new RegistrantList();
7422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    RegistrantList mVoiceCallStartedRegistrants = new RegistrantList();
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // connections dropped during last poll
7822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    ArrayList<GsmConnection> mDroppedDuringPoll
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        = new ArrayList<GsmConnection>(MAX_CONNECTIONS);
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCall mRingingCall = new GsmCall(this);
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // A call that is ringing or (call) waiting
8322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCall mForegroundCall = new GsmCall(this);
8422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCall mBackgroundCall = new GsmCall(this);
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
865e2000b856a7959609e8f15148a3584ec372f865Wink Saville    GsmConnection mPendingMO;
8722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    boolean mHangupPendingMO;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GSMPhone mPhone;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    boolean mDesiredMute = false;    // false = mute off
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    PhoneConstants.State mState = PhoneConstants.State.IDLE;
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
95a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    Call.SrvccState mSrvccState = Call.SrvccState.NONE;
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Events
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constructors
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    GsmCallTracker (GSMPhone phone) {
10322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mPhone = phone;
10422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi = phone.mCi;
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
10922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
113cb104a615d1e44cf39d837c3dbcf9475a5be57ebShriram Ganesh        Rlog.d(LOG_TAG, "GsmCallTracker dispose");
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //Unregister for all events
11522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForCallStateChanged(this);
11622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForOn(this);
11722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForNotAvailable(this);
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearDisconnected();
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
123cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
125ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        Rlog.d(LOG_TAG, "GsmCallTracker finalized");
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Methods
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Public Methods
131cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
13422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallStartedRegistrants.add(r);
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
137cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForVoiceCallStarted(Handler h) {
13922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallStartedRegistrants.remove(h);
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
14522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallEndedRegistrants.add(r);
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
148cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForVoiceCallEnded(Handler h) {
15022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallEndedRegistrants.remove(h);
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    fakeHoldForegroundBeforeDial() {
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List<Connection> connCopy;
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // We need to make a copy here, since fakeHoldBeforeDial()
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // modifies the lists, and we don't want to reverse the order
15922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        connCopy = (List<Connection>) mForegroundCall.mConnections.clone();
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = connCopy.size() ; i < s ; i++) {
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            GsmConnection conn = (GsmConnection)connCopy.get(i);
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            conn.fakeHoldBeforeDial();
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * clirMode is one of the CLIR_ constants
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    synchronized Connection
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException {
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // note that this triggers call state changed notif
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearDisconnected();
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!canDial()) {
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot dial in current state");
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1804bd290e38a3eb70e153b7bffa101a0c9f130e32ew        String origNumber = dialString;
1812d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        dialString = convertNumberIfNecessary(mPhone, dialString);
1824bd290e38a3eb70e153b7bffa101a0c9f130e32ew
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // The new call must be assigned to the foreground call.
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // That call must be idle, so place anything that's
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // there on hold
18622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mForegroundCall.getState() == GsmCall.State.ACTIVE) {
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // this will probably be done by the radio anyway
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // but the dial might fail before this happens
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // and we need to make sure the foreground call is clear
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // for the newly dialed connection
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switchWaitingOrHoldingAndActive();
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Fake local state so that
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // a) foregroundCall is empty for the newly dialed connection
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // b) hasNonHangupStateChanged remains false in the
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // next poll, so that we don't clear a failed dialing call
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            fakeHoldForegroundBeforeDial();
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mForegroundCall.getState() != GsmCall.State.IDLE) {
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //we should have failed in !canDial() above before we get here
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot dial in current state");
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2055e2000b856a7959609e8f15148a3584ec372f865Wink Saville        mPendingMO = new GsmConnection(mPhone.getContext(), checkForTestEmergencyNumber(dialString),
20622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                this, mForegroundCall);
20722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mHangupPendingMO = false;
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
209e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam        if ( mPendingMO.getAddress() == null || mPendingMO.getAddress().length() == 0
210e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                || mPendingMO.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ) {
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Phone number is invalid
213b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen            mPendingMO.mCause = DisconnectCause.INVALID_NUMBER;
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // handlePollCalls() will notice this call not present
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // and will mark it as dropped.
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsWhenSafe();
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Always unmute when initiating a new call
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
222e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam            mCi.dial(mPendingMO.getAddress(), clirMode, uusInfo, obtainCompleteMessage());
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2254bd290e38a3eb70e153b7bffa101a0c9f130e32ew        if (mNumberConverted) {
2264bd290e38a3eb70e153b7bffa101a0c9f130e32ew            mPendingMO.setConverted(origNumber);
2274bd290e38a3eb70e153b7bffa101a0c9f130e32ew            mNumberConverted = false;
2284bd290e38a3eb70e153b7bffa101a0c9f130e32ew        }
2294bd290e38a3eb70e153b7bffa101a0c9f130e32ew
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
23122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2335e2000b856a7959609e8f15148a3584ec372f865Wink Saville        return mPendingMO;
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Connection
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial(String dialString) throws CallStateException {
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return dial(dialString, CommandsInterface.CLIR_DEFAULT, null);
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Connection
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial(String dialString, UUSInfo uusInfo) throws CallStateException {
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo);
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Connection
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial(String dialString, int clirMode) throws CallStateException {
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return dial(dialString, clirMode, null);
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    acceptCall () throws CallStateException {
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // FIXME if SWITCH fails, should retry with ANSWER
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // in case the active/holding call disappeared and this
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // is no longer call waiting
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
25722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.getState() == GsmCall.State.INCOMING) {
258ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.i("phone", "acceptCall: incoming...");
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Always unmute when answering a new call
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
26122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.acceptCall(obtainCompleteMessage());
26222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mRingingCall.getState() == GsmCall.State.WAITING) {
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switchWaitingOrHoldingAndActive();
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("phone not ringing");
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    rejectCall () throws CallStateException {
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // AT+CHLD=0 means "release held or UDUB"
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so if the phone isn't ringing, this could hang up held
27422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.getState().isRinging()) {
27522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.rejectCall(obtainCompleteMessage());
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("phone not ringing");
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    switchWaitingOrHoldingAndActive() throws CallStateException {
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Should we bother with this check?
28422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.getState() == GsmCall.State.INCOMING) {
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot be in the incoming state");
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
28722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.switchWaitingOrHoldingAndActive(
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainCompleteMessage(EVENT_SWITCH_RESULT));
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    conference() {
29422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT));
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
298cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    explicitCallTransfer() {
29922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    clearDisconnected() {
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        internalClearDisconnected();
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
30722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canConference() {
31222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mForegroundCall.getState() == GsmCall.State.ACTIVE
31322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mBackgroundCall.getState() == GsmCall.State.HOLDING
31422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mBackgroundCall.isFull()
31522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mForegroundCall.isFull();
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canDial() {
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean ret;
32122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int serviceState = mPhone.getServiceState().getState();
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String disableCall = SystemProperties.get(
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret = (serviceState != ServiceState.STATE_POWER_OFF)
3265e2000b856a7959609e8f15148a3584ec372f865Wink Saville                && mPendingMO == null
32722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mRingingCall.isRinging()
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && !disableCall.equals("true")
32922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && (!mForegroundCall.getState().isAlive()
33022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    || !mBackgroundCall.getState().isAlive());
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canTransfer() {
33791ce060652d7f9be48ee2eeb771455c9d741564bSungmin Choi        return (mForegroundCall.getState() == GsmCall.State.ACTIVE
33891ce060652d7f9be48ee2eeb771455c9d741564bSungmin Choi                || mForegroundCall.getState() == GsmCall.State.ALERTING
33991ce060652d7f9be48ee2eeb771455c9d741564bSungmin Choi                || mForegroundCall.getState() == GsmCall.State.DIALING)
34091ce060652d7f9be48ee2eeb771455c9d741564bSungmin Choi            && mBackgroundCall.getState() == GsmCall.State.HOLDING;
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Private Instance Methods
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    internalClearDisconnected() {
34722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRingingCall.clearDisconnected();
34822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mForegroundCall.clearDisconnected();
34922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mBackgroundCall.clearDisconnected();
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Obtain a message to use for signalling "invoke getCurrentCalls() when
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * this operation and all other pending operations are complete
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Message
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    obtainCompleteMessage() {
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
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(int what) {
36722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPendingOperations++;
36822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mLastRelevantPoll = null;
36922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNeedsPoll = true;
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
37222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingOperations + ", needsPoll=" + mNeedsPoll);
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return obtainMessage(what);
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    operationComplete() {
37922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPendingOperations--;
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG_POLL) log("operationComplete: pendingOperations=" +
38222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingOperations + ", needsPoll=" + mNeedsPoll);
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
38422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPendingOperations == 0 && mNeedsPoll) {
38522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
38622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.getCurrentCalls(mLastRelevantPoll);
38722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mPendingOperations < 0) {
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // this should never happen
389ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG,"GsmCallTracker.pendingOperations < 0");
39022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPendingOperations = 0;
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    updatePhoneState() {
39622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        PhoneConstants.State oldState = mState;
39722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.isRinging()) {
39822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.RINGING;
3995e2000b856a7959609e8f15148a3584ec372f865Wink Saville        } else if (mPendingMO != null ||
40022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                !(mForegroundCall.isIdle() && mBackgroundCall.isIdle())) {
40122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.OFFHOOK;
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
40369e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            ImsPhone imsPhone = (ImsPhone)mPhone.getImsPhone();
40469e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            if ( mState == PhoneConstants.State.OFFHOOK && (imsPhone != null)){
40569e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com                imsPhone.callEndCleanupHandOverCallIfAny();
40669e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            }
40722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.IDLE;
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
41022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState == PhoneConstants.State.IDLE && oldState != mState) {
41122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceCallEndedRegistrants.notifyRegistrants(
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                new AsyncResult(null, null, null));
41322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (oldState == PhoneConstants.State.IDLE && oldState != mState) {
41422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceCallStartedRegistrants.notifyRegistrants (
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    new AsyncResult(null, null, null));
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
41822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState != oldState) {
41922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyPhoneStateChanged();
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected synchronized void
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handlePollCalls(AsyncResult ar) {
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List polledCalls;
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception == null) {
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            polledCalls = (List)ar.result;
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // just a dummy empty ArrayList to cause the loop
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // to hang up all the calls
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            polledCalls = new ArrayList();
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Radio probably wasn't ready--try again in a bit
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // But don't keep polling if the channel is closed
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsAfterDelay();
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Connection newRinging = null; //or waiting
44283a97603d6e38ca5600cc12780fbfbee0cfe483fYorke Lee        Connection newUnknown = null;
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasNonHangupStateChanged = false;   // Any change besides
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                    // a dropped connection
445368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        boolean hasAnyCallDisconnected = false;
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean needsPollDelay = false;
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean unknownConnectionAppeared = false;
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, curDC = 0, dcSize = polledCalls.size()
45022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                ; i < mConnections.length; i++) {
45122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            GsmConnection conn = mConnections[i];
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DriverCall dc = null;
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // polledCall list is sparse
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (curDC < dcSize) {
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = (DriverCall) polledCalls.get(curDC);
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dc.index == i+1) {
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    curDC++;
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dc = null;
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    conn+", dc=" + dc);
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn == null && dc != null) {
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Connection appeared in CLCC response that we don't know about
4705e2000b856a7959609e8f15148a3584ec372f865Wink Saville                if (mPendingMO != null && mPendingMO.compareTo(dc)) {
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4725e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    if (DBG_POLL) log("poll: pendingMO=" + mPendingMO);
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // It's our pending mobile originating call
4755e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    mConnections[i] = mPendingMO;
4765e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    mPendingMO.mIndex = i;
4775e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    mPendingMO.update(dc);
4785e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    mPendingMO = null;
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Someone has already asked to hangup this call
48122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mHangupPendingMO) {
48222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mHangupPendingMO = false;
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (Phone.DEBUG_PHONE) log(
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    "poll: hangupPendingMO, hangup conn " + i);
48622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            hangup(mConnections[i]);
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (CallStateException ex) {
488ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                            Rlog.e(LOG_TAG, "unexpected error on hangup");
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Do not continue processing this poll
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Wait for hangup and repoll
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
49622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mConnections[i] = new GsmConnection(mPhone.getContext(), dc, this, i);
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4984be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                    Connection hoConnection = getHoConnection(dc);
4994be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                    if (hoConnection != null) {
500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        // Single Radio Voice Call Continuity (SRVCC) completed
5014be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                        mConnections[i].migrateFrom(hoConnection);
5024be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                        if (!hoConnection.isMultiparty()) {
5034be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                            // Remove only if it is not multiparty
5044be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                            mHandoverConnections.remove(hoConnection);
5054be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                        }
506e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        mPhone.notifyHandoverStateChanged(mConnections[i]);
5074be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                    } else if ( mConnections[i].getCall() == mRingingCall ) { // it's a ringing call
5084be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                        newRinging = mConnections[i];
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Something strange happened: a call appeared
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // which is neither a ringing call or one we created.
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Either we've crashed and re-attached to an existing
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // call, or something else (eg, SIM) initiated the call.
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
515ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                        Rlog.i(LOG_TAG,"Phantom call appeared " + dc);
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // If it's a connected call, set the connect time so that
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // it's non-zero.  It may not be accurate, but at least
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // it won't appear as a Missed Call.
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (dc.state != DriverCall.State.ALERTING
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                && dc.state != DriverCall.State.DIALING) {
52222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mConnections[i].onConnectedInOrOut();
5239b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                            if (dc.state == DriverCall.State.HOLDING) {
5249b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                                // We've transitioned into HOLDING
52522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mConnections[i].onStartedHolding();
5269b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                            }
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
52983a97603d6e38ca5600cc12780fbfbee0cfe483fYorke Lee                        newUnknown = mConnections[i];
53083a97603d6e38ca5600cc12780fbfbee0cfe483fYorke Lee
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        unknownConnectionAppeared = true;
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasNonHangupStateChanged = true;
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc == null) {
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Connection missing in CLCC response that we were
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // tracking.
53822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.add(conn);
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Dropped connections are removed from the CallTracker
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // list but kept in the GsmCall list
54122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mConnections[i] = null;
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc != null && !conn.compareTo(dc)) {
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Connection in CLCC response does not match what
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // we were tracking. Assume dropped call and new call
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
54622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.add(conn);
54722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mConnections[i] = new GsmConnection (mPhone.getContext(), dc, this, i);
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
54922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mConnections[i].getCall() == mRingingCall) {
55022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    newRinging = mConnections[i];
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } // else something strange happened
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasNonHangupStateChanged = true;
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                boolean changed;
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                changed = conn.update(dc);
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (REPEAT_POLLING) {
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dc != null) {
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // FIXME with RIL, we should not need this anymore
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((dc.state == DriverCall.State.DIALING
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.ALERTING
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.INCOMING
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.WAITING
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ) {
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Sometimes there's no unsolicited notification
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // for state transitions
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        needsPollDelay = true;
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This is the first poll after an ATD.
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // We expect the pending call to appear in the list
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If it does not, we land here
5825e2000b856a7959609e8f15148a3584ec372f865Wink Saville        if (mPendingMO != null) {
583ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.d(LOG_TAG,"Pending MO dropped before poll fg state:"
58422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            + mForegroundCall.getState());
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5865e2000b856a7959609e8f15148a3584ec372f865Wink Saville            mDroppedDuringPoll.add(mPendingMO);
5875e2000b856a7959609e8f15148a3584ec372f865Wink Saville            mPendingMO = null;
58822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mHangupPendingMO = false;
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (newRinging != null) {
59222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyNewRingingConnection(newRinging);
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // clear the "local hangup" and "missed/rejected call"
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // cases from the "dropped during poll" list
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // These cases need no "last call fail" reason
59822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = mDroppedDuringPoll.size() - 1; i >= 0 ; i--) {
59922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            GsmConnection conn = mDroppedDuringPoll.get(i);
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn.isIncoming() && conn.getConnectTime() == 0) {
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Missed or rejected call
603b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                int cause;
604b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                if (conn.mCause == DisconnectCause.LOCAL) {
605b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                    cause = DisconnectCause.INCOMING_REJECTED;
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
607b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                    cause = DisconnectCause.INCOMING_MISSED;
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
61122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    log("missed/rejected call, conn.cause=" + conn.mCause);
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("setting cause to " + cause);
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
61422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.remove(i);
615368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann                hasAnyCallDisconnected |= conn.onDisconnect(cause);
616b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen            } else if (conn.mCause == DisconnectCause.LOCAL
617b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                    || conn.mCause == DisconnectCause.INVALID_NUMBER) {
61822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.remove(i);
619368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann                hasAnyCallDisconnected |= conn.onDisconnect(conn.mCause);
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
623de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade        /* Disconnect any pending Handover connections */
624de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade        for (Connection hoConnection : mHandoverConnections) {
625de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade            log("handlePollCalls - disconnect hoConn= " + hoConnection.toString());
626de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade            ((ImsPhoneConnection)hoConnection).onDisconnect(DisconnectCause.NOT_VALID);
627de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade            mHandoverConnections.remove(hoConnection);
628de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade        }
629de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Any non-local disconnects: determine cause
63122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mDroppedDuringPoll.size() > 0) {
63222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.getLastCallFailCause(
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (needsPollDelay) {
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsAfterDelay();
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Cases when we can no longer keep disconnected Connection's
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // with their previous calls
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 1) the phone has started to ring
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 2) A Call/Connection object has changed state...
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //    we may have switched or held or answered (but not hung up)
645368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        if (newRinging != null || hasNonHangupStateChanged || hasAnyCallDisconnected) {
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            internalClearDisconnected();
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (unknownConnectionAppeared) {
65283a97603d6e38ca5600cc12780fbfbee0cfe483fYorke Lee            mPhone.notifyUnknownConnection(newUnknown);
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
655368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        if (hasNonHangupStateChanged || newRinging != null || hasAnyCallDisconnected) {
65622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyPreciseCallStateChanged();
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //dumpState();
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleRadioNotAvailable() {
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // handlePollCalls will clear out its
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // call list when it gets the CommandException
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // error result from this
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pollCallsWhenSafe();
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dumpState() {
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List l;
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
67422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Rlog.i(LOG_TAG,"Phone State:" + mState);
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
67622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Rlog.i(LOG_TAG,"Ringing call: " + mRingingCall.toString());
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
67822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        l = mRingingCall.getConnections();
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = l.size(); i < s; i++) {
680ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.i(LOG_TAG,l.get(i).toString());
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
68322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Rlog.i(LOG_TAG,"Foreground call: " + mForegroundCall.toString());
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
68522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        l = mForegroundCall.getConnections();
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = l.size(); i < s; i++) {
687ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.i(LOG_TAG,l.get(i).toString());
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
69022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Rlog.i(LOG_TAG,"Background call: " + mBackgroundCall.toString());
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
69222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        l = mBackgroundCall.getConnections();
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = l.size(); i < s; i++) {
694ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.i(LOG_TAG,l.get(i).toString());
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from GsmConnection
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    hangup (GsmConnection conn) throws CallStateException {
70322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (conn.mOwner != this) {
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException ("GsmConnection " + conn
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    + "does not belong to GsmCallTracker " + this);
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7085e2000b856a7959609e8f15148a3584ec372f865Wink Saville        if (conn == mPendingMO) {
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // We're hanging up an outgoing call that doesn't have it's
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // GSM index assigned yet
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
71322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mHangupPendingMO = true;
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
71622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.hangupConnection (conn.getGSMIndex(), obtainCompleteMessage());
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (CallStateException ex) {
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Ignore "connection not found"
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Call may have hung up already
720ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                Rlog.w(LOG_TAG,"GsmCallTracker WARN: hangup() on absent connection "
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                + conn);
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        conn.onHangupLocal();
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    separate (GsmConnection conn) throws CallStateException {
73022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (conn.mOwner != this) {
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException ("GsmConnection " + conn
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    + "does not belong to GsmCallTracker " + this);
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
73522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.separateConnection (conn.getGSMIndex(),
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainCompleteMessage(EVENT_SEPARATE_RESULT));
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Ignore "connection not found"
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Call may have hung up already
740ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.w(LOG_TAG,"GsmCallTracker WARN: separate() on absent connection "
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                          + conn);
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from GSMPhone
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setMute(boolean mute) {
74922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mDesiredMute = mute;
75022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setMute(mDesiredMute, null);
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ boolean
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getMute() {
75522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mDesiredMute;
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from GsmCall
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */ void
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    hangup (GsmCall call) throws CallStateException {
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (call.getConnections().size() == 0) {
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("no connections in call");
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
76722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (call == mRingingCall) {
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
76922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.hangupWaitingOrBackground(obtainCompleteMessage());
77022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (call == mForegroundCall) {
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (call.isDialingOrAlerting()) {
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("(foregnd) hangup dialing or alerting...");
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangup((GsmConnection)(call.getConnections().get(0)));
7763e0dd6a897acb42e665b429dcd6ae67f19d76063MUDUMBA ANANTH            } else if (mRingingCall.isRinging()) {
7773e0dd6a897acb42e665b429dcd6ae67f19d76063MUDUMBA ANANTH                // Do not auto-answer ringing on CHUP, instead just end active calls
7783e0dd6a897acb42e665b429dcd6ae67f19d76063MUDUMBA ANANTH                log("hangup all conns in active/background call, without affecting ringing call");
7793e0dd6a897acb42e665b429dcd6ae67f19d76063MUDUMBA ANANTH                hangupAllConnections(call);
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupForegroundResumeBackground();
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
78322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (call == mBackgroundCall) {
78422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mRingingCall.isRinging()) {
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("hangup all conns in background call");
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAllConnections(call);
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupWaitingOrBackground();
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new RuntimeException ("GsmCall " + call +
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "does not belong to GsmCallTracker " + this);
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        call.onHangupLocal();
79822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupWaitingOrBackground() {
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
80422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.hangupWaitingOrBackground(obtainCompleteMessage());
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupForegroundResumeBackground() {
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
81022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.hangupForegroundResumeBackground(obtainCompleteMessage());
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupConnectionByIndex(GsmCall call, int index)
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws CallStateException {
81522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int count = call.mConnections.size();
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
81722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            GsmConnection cn = (GsmConnection)call.mConnections.get(i);
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cn.getGSMIndex() == index) {
81922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.hangupConnection(index, obtainCompleteMessage());
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        throw new CallStateException("no gsm index found");
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
827cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    void hangupAllConnections(GsmCall call) {
8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
82922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            int count = call.mConnections.size();
8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0; i < count; i++) {
83122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                GsmConnection cn = (GsmConnection)call.mConnections.get(i);
83222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.hangupConnection(cn.getGSMIndex(), obtainCompleteMessage());
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
835ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
8400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    GsmConnection getConnectionByIndex(GsmCall call, int index)
8410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws CallStateException {
84222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int count = call.mConnections.size();
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
84422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            GsmConnection cn = (GsmConnection)call.mConnections.get(i);
8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cn.getGSMIndex() == index) {
8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return cn;
8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Phone.SuppService getFailedService(int what) {
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (what) {
8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SWITCH_RESULT:
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.SWITCH;
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CONFERENCE_RESULT:
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.CONFERENCE;
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SEPARATE_RESULT:
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.SEPARATE;
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_ECT_RESULT:
8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return Phone.SuppService.TRANSFER;
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return Phone.SuppService.UNKNOWN;
8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //****** Overridden from Handler
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
869cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage (Message msg) {
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8745e2000b856a7959609e8f15148a3584ec372f865Wink Saville        if (!mPhone.mIsTheCurrentActivePhone) {
8755e2000b856a7959609e8f15148a3584ec372f865Wink Saville            Rlog.e(LOG_TAG, "Received message " + msg +
8765e2000b856a7959609e8f15148a3584ec372f865Wink Saville                    "[" + msg.what + "] while being destroyed. Ignoring.");
8775e2000b856a7959609e8f15148a3584ec372f865Wink Saville            return;
8785e2000b856a7959609e8f15148a3584ec372f865Wink Saville        }
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_CALLS_RESULT:
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
88322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (msg == mLastRelevantPoll) {
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG_POLL) log(
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
88622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNeedsPoll = false;
88722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mLastRelevantPoll = null;
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    handlePollCalls((AsyncResult)msg.obj);
8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_OPERATION_COMPLETE:
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SWITCH_RESULT:
8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CONFERENCE_RESULT:
8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SEPARATE_RESULT:
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_ECT_RESULT:
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception != null) {
90322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPhone.notifySuppServiceFailed(getFailedService(msg.what));
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_LAST_CALL_FAIL_CAUSE:
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int causeCode;
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception != null) {
9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // An exception occurred...just treat the disconnect
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // cause as "normal"
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode = CallFailCause.NORMAL_CLEARING;
918ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                    Rlog.i(LOG_TAG,
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "Exception during getLastCallFailCause, assuming normal disconnect");
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode = ((int[])ar.result)[0];
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Log the causeCode if its not normal
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (causeCode == CallFailCause.NO_CIRCUIT_AVAIL ||
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.TEMPORARY_FAILURE ||
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.SWITCHING_CONGESTION ||
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.CHANNEL_NOT_AVAIL ||
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.QOS_NOT_AVAIL ||
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.BEARER_NOT_AVAIL ||
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode == CallFailCause.ERROR_UNSPECIFIED) {
93122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    EventLog.writeEvent(EventLogTags.CALL_DROP,
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            causeCode, loc != null ? loc.getCid() : -1,
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            TelephonyManager.getDefault().getNetworkType());
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
93722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                for (int i = 0, s =  mDroppedDuringPoll.size()
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ; i < s ; i++
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
94022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    GsmConnection conn = mDroppedDuringPoll.get(i);
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    conn.onRemoteDisconnect(causeCode);
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updatePhoneState();
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
94722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.notifyPreciseCallStateChanged();
94822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.clear();
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_REPOLL_AFTER_DELAY:
9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CALL_STATE_CHANGE:
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollCallsWhenSafe();
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_AVAILABLE:
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleRadioAvailable();
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_NOT_AVAILABLE:
9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleRadioNotAvailable();
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
966cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String msg) {
968ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        Rlog.d(LOG_TAG, "[GsmCallTracker] " + msg);
9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("GsmCallTracker extends:");
9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
97522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println("mConnections: length=" + mConnections.length);
97622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for(int i=0; i < mConnections.length; i++) {
97722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            pw.printf("  mConnections[%d]=%s\n", i, mConnections[i]);
97822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        }
97922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mVoiceCallEndedRegistrants=" + mVoiceCallEndedRegistrants);
98022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mVoiceCallStartedRegistrants=" + mVoiceCallStartedRegistrants);
98122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDroppedDuringPoll: size=" + mDroppedDuringPoll.size());
98222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for(int i = 0; i < mDroppedDuringPoll.size(); i++) {
98322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            pw.printf( "  mDroppedDuringPoll[%d]=%s\n", i, mDroppedDuringPoll.get(i));
98422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        }
98522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mRingingCall=" + mRingingCall);
98622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mForegroundCall=" + mForegroundCall);
98722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mBackgroundCall=" + mBackgroundCall);
9885e2000b856a7959609e8f15148a3584ec372f865Wink Saville        pw.println(" mPendingMO=" + mPendingMO);
98922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mHangupPendingMO=" + mHangupPendingMO);
99022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPhone=" + mPhone);
99122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDesiredMute=" + mDesiredMute);
99222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mState=" + mState);
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
994b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    @Override
995b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    public PhoneConstants.State getState() {
996b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        return mState;
997b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    }
9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
999