GsmCdmaCallTracker.java revision b79f845a0451895b0f0b8a926a8571511d476ce8
10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.cdma;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
24b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensenimport android.telephony.DisconnectCause;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.PhoneNumberUtils;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
27ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties;
292d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Yingimport android.text.TextUtils;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CallStateException;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CallTracker;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Connection;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DriverCall;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Phone;
37e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingamimport com.android.internal.telephony.PhoneBase;
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.PhoneConstants;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.TelephonyProperties;
40de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangadeimport com.android.internal.telephony.imsphone.ImsPhoneConnection;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic final class CdmaCallTracker extends CallTracker {
52cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "CdmaCallTracker";
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean REPEAT_POLLING = false;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final boolean DBG_POLL = false;
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constants
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
60d62a7cecd0451592222d73995dd53074aa6f98a5Sungmin Choi    static final int MAX_CONNECTIONS = 8;
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MAX_CONNECTIONS_PER_CALL = 1; // only 1 connection allowed per call
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Variables
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CdmaConnection mConnections[] = new CdmaConnection[MAX_CONNECTIONS];
6622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    RegistrantList mVoiceCallEndedRegistrants = new RegistrantList();
6722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    RegistrantList mVoiceCallStartedRegistrants = new RegistrantList();
6822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    RegistrantList mCallWaitingRegistrants =  new RegistrantList();
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // connections dropped during last poll
7222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    ArrayList<CdmaConnection> mDroppedDuringPoll
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        = new ArrayList<CdmaConnection>(MAX_CONNECTIONS);
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CdmaCall mRingingCall = new CdmaCall(this);
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // A call that is ringing or (call) waiting
7722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CdmaCall mForegroundCall = new CdmaCall(this);
7822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CdmaCall mBackgroundCall = new CdmaCall(this);
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CdmaConnection mPendingMO;
8122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    boolean mHangupPendingMO;
8222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    boolean mPendingCallInEcm=false;
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean mIsInEmergencyCall = false;
8422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CDMAPhone mPhone;
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    boolean mDesiredMute = false;    // false = mute off
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mPendingCallClirMode;
8922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    PhoneConstants.State mState = PhoneConstants.State.IDLE;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mIsEcmTimerCanceled = false;
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
93bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao    private int m3WayCallFlashDelay = 0;
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville//    boolean needsPoll;
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Events
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constructors
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CdmaCallTracker(CDMAPhone phone) {
10222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone = phone;
10322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi = phone.mCi;
10422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
10522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
10622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
10722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null);
10822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mForegroundCall.setGeneric(false);
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
112cb104a615d1e44cf39d837c3dbcf9475a5be57ebShriram Ganesh        Rlog.d(LOG_TAG, "CdmaCallTracker dispose");
113cb104a615d1e44cf39d837c3dbcf9475a5be57ebShriram Ganesh        mCi.unregisterForLineControlInfo(this);
11422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForCallStateChanged(this);
11522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForOn(this);
11622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForNotAvailable(this);
11722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForCallWaitingInfo(this);
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearDisconnected();
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
125ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        Rlog.d(LOG_TAG, "CdmaCallTracker 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        // Notify if in call when registering
13622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState != PhoneConstants.State.IDLE) {
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant(new AsyncResult(null, null, null));
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
140cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForVoiceCallStarted(Handler h) {
14222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallStartedRegistrants.remove(h);
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
145cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
14822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallEndedRegistrants.add(r);
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
151cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForVoiceCallEnded(Handler h) {
15322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceCallEndedRegistrants.remove(h);
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForCallWaiting(Handler h, int what, Object obj) {
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant (h, what, obj);
15822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCallWaitingRegistrants.add(r);
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForCallWaiting(Handler h) {
16222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCallWaitingRegistrants.remove(h);
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * clirMode is one of the CLIR_ constants
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Connection
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial (String dialString, int clirMode) throws CallStateException {
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // note that this triggers call state changed notif
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearDisconnected();
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!canDial()) {
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot dial in current state");
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1772d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        String origNumber = dialString;
1782d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        String operatorIsoContry = mPhone.getSystemProperty(
1792d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying                TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
1802d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        String simIsoContry = mPhone.getSystemProperty(
1812d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying                TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, "");
1822d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        boolean internationalRoaming = !TextUtils.isEmpty(operatorIsoContry)
1832d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying                && !TextUtils.isEmpty(simIsoContry)
1842d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying                && !simIsoContry.equals(operatorIsoContry);
1852d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        if (internationalRoaming) {
1862d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            if ("us".equals(simIsoContry)) {
1872d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying                internationalRoaming = internationalRoaming && !"vi".equals(operatorIsoContry);
1882d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            } else if ("vi".equals(simIsoContry)) {
1892d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying                internationalRoaming = internationalRoaming && !"us".equals(operatorIsoContry);
1902d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            }
1912d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        }
1922d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        if (internationalRoaming) {
1932d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            dialString = convertNumberIfNecessary(mPhone, dialString);
1942d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        }
1952d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isPhoneInEcmMode = inEcm.equals("true");
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean isEmergencyCall =
199f4f5308a309d43fcfca8d0d5fbb54bc38c82ca3fYorke Lee                PhoneNumberUtils.isLocalEmergencyNumber(mPhone.getContext(), dialString);
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Cancel Ecm timer if a second emergency call is originating in Ecm mode
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (isPhoneInEcmMode && isEmergencyCall) {
203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            handleEcmTimer(CDMAPhone.CANCEL_ECM_TIMER);
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // We are initiating a call therefore even if we previously
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // didn't know the state (i.e. Generic was true) we now know
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // and therefore can set Generic to false.
20922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mForegroundCall.setGeneric(false);
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // The new call must be assigned to the foreground call.
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // That call must be idle, so place anything that's
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // there on hold
21422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mForegroundCall.getState() == CdmaCall.State.ACTIVE) {
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return dialThreeWay(dialString);
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPendingMO = new CdmaConnection(mPhone.getContext(), checkForTestEmergencyNumber(dialString),
21922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                this, mForegroundCall);
22022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mHangupPendingMO = false;
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
222e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam        if ( mPendingMO.getAddress() == null || mPendingMO.getAddress().length() == 0
223e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                || mPendingMO.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0 ) {
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Phone number is invalid
225b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen            mPendingMO.mCause = DisconnectCause.INVALID_NUMBER;
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // handlePollCalls() will notice this call not present
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // and will mark it as dropped.
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsWhenSafe();
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Always unmute when initiating a new call
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Check data call
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            disableDataCallInEmergencyCall(dialString);
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
239e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                mCi.dial(mPendingMO.getAddress(), clirMode, obtainCompleteMessage());
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
24122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.exitEmergencyCallbackMode();
24222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
24322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingCallClirMode=clirMode;
24422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingCallInEcm=true;
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2482d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        if (mNumberConverted) {
2492d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            mPendingMO.setConverted(origNumber);
2502d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying            mNumberConverted = false;
2512d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying        }
2522d265969ca301ba3720458ea9da2ec8d6a18bb8dXia Ying
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
25422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
25622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mPendingMO;
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    Connection
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dial (String dialString) throws CallStateException {
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return dial(dialString, CommandsInterface.CLIR_DEFAULT);
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Connection
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    dialThreeWay (String dialString) {
26722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mForegroundCall.isIdle()) {
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Check data call
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            disableDataCallInEmergencyCall(dialString);
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Attach the new connection to foregroundCall
27222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPendingMO = new CdmaConnection(mPhone.getContext(),
27322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                checkForTestEmergencyNumber(dialString), this, mForegroundCall);
274bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            // Some network need a empty flash before sending the normal one
275bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            m3WayCallFlashDelay = mPhone.getContext().getResources()
276bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                    .getInteger(com.android.internal.R.integer.config_cdma_3waycall_flash_delay);
277bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            if (m3WayCallFlashDelay > 0) {
278bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                mCi.sendCDMAFeatureCode("", obtainMessage(EVENT_THREE_WAY_DIAL_BLANK_FLASH));
279bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            } else {
280bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                mCi.sendCDMAFeatureCode(mPendingMO.getAddress(),
281bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                        obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
282bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            }
28322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return mPendingMO;
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    acceptCall() throws CallStateException {
29022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.getState() == CdmaCall.State.INCOMING) {
291ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.i("phone", "acceptCall: incoming...");
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Always unmute when answering a new call
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setMute(false);
29422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.acceptCall(obtainCompleteMessage());
29522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mRingingCall.getState() == CdmaCall.State.WAITING) {
29622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CdmaConnection cwConn = (CdmaConnection)(mRingingCall.getLatestConnection());
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Since there is no network response for supplimentary
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // service for CDMA, we assume call waiting is answered.
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // ringing Call state change to idle is in CdmaCall.detach
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // triggered by updateParent.
30222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            cwConn.updateParent(mRingingCall, mForegroundCall);
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cwConn.onConnectedInOrOut();
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            updatePhoneState();
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switchWaitingOrHoldingAndActive();
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("phone not ringing");
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    rejectCall () throws CallStateException {
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // AT+CHLD=0 means "release held or UDUB"
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so if the phone isn't ringing, this could hang up held
31522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.getState().isRinging()) {
31622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.rejectCall(obtainCompleteMessage());
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("phone not ringing");
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    switchWaitingOrHoldingAndActive() throws CallStateException {
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Should we bother with this check?
32522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.getState() == CdmaCall.State.INCOMING) {
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("cannot be in the incoming state");
32722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mForegroundCall.getConnections().size() > 1) {
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            flashAndSetGenericTrue();
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Send a flash command to CDMA network for putting the other party on hold.
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // For CDMA networks which do not support this the user would just hear a beep
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // from the network. For CDMA networks which do support it will put the other
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // party on hold.
33422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
339cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    conference() {
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Should we be checking state?
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        flashAndSetGenericTrue();
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    explicitCallTransfer() {
34622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    clearDisconnected() {
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        internalClearDisconnected();
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
35422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canConference() {
35922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mForegroundCall.getState() == CdmaCall.State.ACTIVE
36022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mBackgroundCall.getState() == CdmaCall.State.HOLDING
36122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mBackgroundCall.isFull()
36222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mForegroundCall.isFull();
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canDial() {
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean ret;
36822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int serviceState = mPhone.getServiceState().getState();
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String disableCall = SystemProperties.get(
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret = (serviceState != ServiceState.STATE_POWER_OFF)
37322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mPendingMO == null
37422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && !mRingingCall.isRinging()
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && !disableCall.equals("true")
37622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && (!mForegroundCall.getState().isAlive()
37722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    || (mForegroundCall.getState() == CdmaCall.State.ACTIVE)
37822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    || !mBackgroundCall.getState().isAlive());
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!ret) {
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log(String.format("canDial is false\n" +
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "((serviceState=%d) != ServiceState.STATE_POWER_OFF)::=%s\n" +
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "&& pendingMO == null::=%s\n" +
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "&& !ringingCall.isRinging()::=%s\n" +
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "&& !disableCall.equals(\"true\")::=%s\n" +
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "&& (!foregroundCall.getState().isAlive()::=%s\n" +
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "   || foregroundCall.getState() == CdmaCall.State.ACTIVE::=%s\n" +
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                              "   ||!backgroundCall.getState().isAlive())::=%s)",
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    serviceState,
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    serviceState != ServiceState.STATE_POWER_OFF,
39122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingMO == null,
39222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    !mRingingCall.isRinging(),
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !disableCall.equals("true"),
39422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    !mForegroundCall.getState().isAlive(),
39522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mForegroundCall.getState() == CdmaCall.State.ACTIVE,
39622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    !mBackgroundCall.getState().isAlive()));
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    canTransfer() {
403ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        Rlog.e(LOG_TAG, "canTransfer: not possible in CDMA");
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Private Instance Methods
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    internalClearDisconnected() {
41122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRingingCall.clearDisconnected();
41222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mForegroundCall.clearDisconnected();
41322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mBackgroundCall.clearDisconnected();
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Obtain a message to use for signalling "invoke getCurrentCalls() when
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * this operation and all other pending operations are complete
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Message
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    obtainCompleteMessage() {
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Obtain a message to use for signalling "invoke getCurrentCalls() when
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * this operation and all other pending operations are complete
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Message
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    obtainCompleteMessage(int what) {
43122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPendingOperations++;
43222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mLastRelevantPoll = null;
43322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNeedsPoll = true;
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
43622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingOperations + ", needsPoll=" + mNeedsPoll);
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return obtainMessage(what);
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    operationComplete() {
44322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPendingOperations--;
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG_POLL) log("operationComplete: pendingOperations=" +
44622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingOperations + ", needsPoll=" + mNeedsPoll);
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
44822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPendingOperations == 0 && mNeedsPoll) {
44922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
45022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.getCurrentCalls(mLastRelevantPoll);
45122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mPendingOperations < 0) {
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // this should never happen
453ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG,"CdmaCallTracker.pendingOperations < 0");
45422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPendingOperations = 0;
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    updatePhoneState() {
46222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        PhoneConstants.State oldState = mState;
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
46422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRingingCall.isRinging()) {
46522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.RINGING;
46622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mPendingMO != null ||
46722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                !(mForegroundCall.isIdle() && mBackgroundCall.isIdle())) {
46822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.OFFHOOK;
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
47022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = PhoneConstants.State.IDLE;
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
47322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState == PhoneConstants.State.IDLE && oldState != mState) {
47422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceCallEndedRegistrants.notifyRegistrants(
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                new AsyncResult(null, null, null));
47622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (oldState == PhoneConstants.State.IDLE && oldState != mState) {
47722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceCallStartedRegistrants.notifyRegistrants (
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    new AsyncResult(null, null, null));
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) {
48122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            log("update phone state, old=" + oldState + " new="+ mState);
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
48322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState != oldState) {
48422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyPhoneStateChanged();
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // ***** Overwritten from CallTracker
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
490cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handlePollCalls(AsyncResult ar) {
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List polledCalls;
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception == null) {
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            polledCalls = (List)ar.result;
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // just a dummy empty ArrayList to cause the loop
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // to hang up all the calls
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            polledCalls = new ArrayList();
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Radio probably wasn't ready--try again in a bit
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // But don't keep polling if the channel is closed
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsAfterDelay();
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Connection newRinging = null; //or waiting
5094a00d523459470e604728784d36a3dd2a0f6c331Yorke Lee        Connection newUnknown = null;
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasNonHangupStateChanged = false;   // Any change besides
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                                    // a dropped connection
512368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        boolean hasAnyCallDisconnected = false;
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean needsPollDelay = false;
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean unknownConnectionAppeared = false;
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, curDC = 0, dcSize = polledCalls.size()
51722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                ; i < mConnections.length; i++) {
51822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CdmaConnection conn = mConnections[i];
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DriverCall dc = null;
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // polledCall list is sparse
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (curDC < dcSize) {
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = (DriverCall) polledCalls.get(curDC);
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dc.index == i+1) {
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    curDC++;
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dc = null;
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    conn+", dc=" + dc);
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn == null && dc != null) {
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Connection appeared in CLCC response that we don't know about
53722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mPendingMO != null && mPendingMO.compareTo(dc)) {
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
53922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (DBG_POLL) log("poll: pendingMO=" + mPendingMO);
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // It's our pending mobile originating call
54222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mConnections[i] = mPendingMO;
54322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingMO.mIndex = i;
54422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingMO.update(dc);
54522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingMO = null;
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Someone has already asked to hangup this call
54822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mHangupPendingMO) {
54922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mHangupPendingMO = false;
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Re-start Ecm timer when an uncompleted emergency call ends
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (mIsEcmTimerCanceled) {
552cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                            handleEcmTimer(CDMAPhone.RESTART_ECM_TIMER);
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (Phone.DEBUG_PHONE) log(
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    "poll: hangupPendingMO, hangup conn " + i);
55822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            hangup(mConnections[i]);
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (CallStateException ex) {
560ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                            Rlog.e(LOG_TAG, "unexpected error on hangup");
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Do not continue processing this poll
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Wait for hangup and repoll
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (Phone.DEBUG_PHONE) {
56922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        log("pendingMo=" + mPendingMO + ", dc=" + dc);
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
571e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                    mConnections[i] = new CdmaConnection(mPhone.getContext(), dc, this, i);
572e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam
5734be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                    Connection hoConnection = getHoConnection(dc);
5744be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                    if (hoConnection != null) {
575e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        // Single Radio Voice Call Continuity (SRVCC) completed
5764be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                        mConnections[i].migrateFrom(hoConnection);
5774be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                        mHandoverConnections.remove(hoConnection);
578e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        mPhone.notifyHandoverStateChanged(mConnections[i]);
579e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                    } else {
580e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        // find if the MT call is a new ring or unknown connection
581e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        newRinging = checkMtFindNewRinging(dc,i);
582e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        if (newRinging == null) {
583e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                            unknownConnectionAppeared = true;
584e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                        }
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    checkAndEnableDataCallAfterEmergencyCallDropped();
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasNonHangupStateChanged = true;
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc == null) {
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This case means the RIL has no more active call anymore and
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // we need to clean up the foregroundCall and ringingCall.
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Loop through foreground call connections as
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // it contains the known logical connections.
59422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                int count = mForegroundCall.mConnections.size();
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                for (int n = 0; n < count; n++) {
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (Phone.DEBUG_PHONE) log("adding fgCall cn " + n + " to droppedDuringPoll");
59722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    CdmaConnection cn = (CdmaConnection)mForegroundCall.mConnections.get(n);
59822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mDroppedDuringPoll.add(cn);
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
60022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                count = mRingingCall.mConnections.size();
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Loop through ringing call connections as
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // it may contain the known logical connections.
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                for (int n = 0; n < count; n++) {
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (Phone.DEBUG_PHONE) log("adding rgCall cn " + n + " to droppedDuringPoll");
60522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    CdmaConnection cn = (CdmaConnection)mRingingCall.mConnections.get(n);
60622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mDroppedDuringPoll.add(cn);
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
60822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mForegroundCall.setGeneric(false);
60922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRingingCall.setGeneric(false);
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Re-start Ecm timer when the connected emergency call ends
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (mIsEcmTimerCanceled) {
613cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    handleEcmTimer(CDMAPhone.RESTART_ECM_TIMER);
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // If emergency call is not going through while dialing
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                checkAndEnableDataCallAfterEmergencyCallDropped();
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Dropped connections are removed from the CallTracker
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // list but kept in the Call list
62022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mConnections[i] = null;
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Call collision case
623121eaf87527829acc2a909e4a0515cada28a674eEtan Cohen                if (conn.isIncoming() != dc.isMT) {
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (dc.isMT == true){
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Mt call takes precedence than Mo,drops Mo
62622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mDroppedDuringPoll.add(conn);
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // find if the MT call is a new ring or unknown connection
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        newRinging = checkMtFindNewRinging(dc,i);
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (newRinging == null) {
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            unknownConnectionAppeared = true;
6314a00d523459470e604728784d36a3dd2a0f6c331Yorke Lee                            newUnknown = conn;
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        checkAndEnableDataCallAfterEmergencyCallDropped();
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Call info stored in conn is not consistent with the call info from dc.
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // We should follow the rule of MT calls taking precedence over MO calls
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // when there is conflict, so here we drop the call info from dc and
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // continue to use the call info from conn, and only take a log.
639ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                        Rlog.e(LOG_TAG,"Error in RIL, Phantom call appeared " + dc);
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    boolean changed;
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    changed = conn.update(dc);
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (REPEAT_POLLING) {
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dc != null) {
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // FIXME with RIL, we should not need this anymore
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((dc.state == DriverCall.State.DIALING
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.ALERTING
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.INCOMING
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || (dc.state == DriverCall.State.WAITING
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ) {
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Sometimes there's no unsolicited notification
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // for state transitions
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        needsPollDelay = true;
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This is the first poll after an ATD.
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // We expect the pending call to appear in the list
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If it does not, we land here
67122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPendingMO != null) {
672ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.d(LOG_TAG,"Pending MO dropped before poll fg state:"
67322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            + mForegroundCall.getState());
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
67522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mDroppedDuringPoll.add(mPendingMO);
67622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPendingMO = null;
67722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mHangupPendingMO = false;
67822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if( mPendingCallInEcm) {
67922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPendingCallInEcm = false;
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (newRinging != null) {
68422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyNewRingingConnection(newRinging);
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // clear the "local hangup" and "missed/rejected call"
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // cases from the "dropped during poll" list
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // These cases need no "last call fail" reason
69022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = mDroppedDuringPoll.size() - 1; i >= 0 ; i--) {
69122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CdmaConnection conn = mDroppedDuringPoll.get(i);
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (conn.isIncoming() && conn.getConnectTime() == 0) {
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Missed or rejected call
695b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                int cause;
696b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                if (conn.mCause == DisconnectCause.LOCAL) {
697b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                    cause = DisconnectCause.INCOMING_REJECTED;
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
699b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                    cause = DisconnectCause.INCOMING_MISSED;
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
70322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    log("missed/rejected call, conn.cause=" + conn.mCause);
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("setting cause to " + cause);
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
70622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.remove(i);
707368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann                hasAnyCallDisconnected |= conn.onDisconnect(cause);
708b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen            } else if (conn.mCause == DisconnectCause.LOCAL
709b7b7a62112b79571adf74372c5f5366fd62d0031Anders Kristensen                    || conn.mCause == DisconnectCause.INVALID_NUMBER) {
71022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.remove(i);
711368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann                hasAnyCallDisconnected |= conn.onDisconnect(conn.mCause);
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
715de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade        /* Disconnect any pending Handover connections */
716de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade        for (Connection hoConnection : mHandoverConnections) {
717de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade            log("handlePollCalls - disconnect hoConn= " + hoConnection.toString());
718de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade            ((ImsPhoneConnection)hoConnection).onDisconnect(DisconnectCause.NOT_VALID);
719de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade            mHandoverConnections.remove(hoConnection);
720de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade        }
721de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Any non-local disconnects: determine cause
72322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mDroppedDuringPoll.size() > 0) {
72422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.getLastCallFailCause(
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (needsPollDelay) {
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollCallsAfterDelay();
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Cases when we can no longer keep disconnected Connection's
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // with their previous calls
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 1) the phone has started to ring
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 2) A Call/Connection object has changed state...
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //    we may have switched or held or answered (but not hung up)
737368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        if (newRinging != null || hasNonHangupStateChanged || hasAnyCallDisconnected) {
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            internalClearDisconnected();
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (unknownConnectionAppeared) {
7444a00d523459470e604728784d36a3dd2a0f6c331Yorke Lee            mPhone.notifyUnknownConnection(newUnknown);
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
747368e873b65e60268521b3c74110a9b2abe8086acDanny Baumann        if (hasNonHangupStateChanged || newRinging != null || hasAnyCallDisconnected) {
74822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyPreciseCallStateChanged();
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //dumpState();
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from CdmaConnection
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    hangup (CdmaConnection conn) throws CallStateException {
75722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (conn.mOwner != this) {
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException ("CdmaConnection " + conn
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    + "does not belong to CdmaCallTracker " + this);
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
76222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (conn == mPendingMO) {
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // We're hanging up an outgoing call that doesn't have it's
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // GSM index assigned yet
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
76722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mHangupPendingMO = true;
76822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if ((conn.getCall() == mRingingCall)
76922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && (mRingingCall.getState() == CdmaCall.State.WAITING)) {
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Handle call waiting hang up case.
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The ringingCall state will change to IDLE in CdmaCall.detach
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // if the ringing call connection size is 0. We don't specifically
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // set the ringing call state to IDLE here to avoid a race condition
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // where a new call waiting could get a hang up from an old call
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // waiting ringingCall.
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // PhoneApp does the call log itself since only PhoneApp knows
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // the hangup reason is user ignoring or timing out. So conn.onDisconnect()
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // is not called here. Instead, conn.onLocalDisconnect() is called.
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            conn.onLocalDisconnect();
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            updatePhoneState();
78322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyPreciseCallStateChanged();
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
78722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage());
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (CallStateException ex) {
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Ignore "connection not found"
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Call may have hung up already
791ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                Rlog.w(LOG_TAG,"CdmaCallTracker WARN: hangup() on absent connection "
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                + conn);
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        conn.onHangupLocal();
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    separate (CdmaConnection conn) throws CallStateException {
80122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (conn.mOwner != this) {
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException ("CdmaConnection " + conn
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    + "does not belong to CdmaCallTracker " + this);
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
80622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.separateConnection (conn.getCDMAIndex(),
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainCompleteMessage(EVENT_SEPARATE_RESULT));
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Ignore "connection not found"
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Call may have hung up already
811ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.w(LOG_TAG,"CdmaCallTracker WARN: separate() on absent connection "
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                          + conn);
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from CDMAPhone
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ void
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setMute(boolean mute) {
82022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mDesiredMute = mute;
82122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setMute(mDesiredMute, null);
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*package*/ boolean
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getMute() {
82622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mDesiredMute;
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from CdmaCall
8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */ void
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    hangup (CdmaCall call) throws CallStateException {
8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (call.getConnections().size() == 0) {
8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new CallStateException("no connections in call");
8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
83822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (call == mRingingCall) {
8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
84022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.hangupWaitingOrBackground(obtainCompleteMessage());
84122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (call == mForegroundCall) {
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (call.isDialingOrAlerting()) {
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("(foregnd) hangup dialing or alerting...");
8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangup((CdmaConnection)(call.getConnections().get(0)));
8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupForegroundResumeBackground();
8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
85022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (call == mBackgroundCall) {
85122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mRingingCall.isRinging()) {
8520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (Phone.DEBUG_PHONE) {
8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("hangup all conns in background call");
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAllConnections(call);
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupWaitingOrBackground();
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new RuntimeException ("CdmaCall " + call +
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "does not belong to CdmaCallTracker " + this);
8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        call.onHangupLocal();
86522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupWaitingOrBackground() {
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
87122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.hangupWaitingOrBackground(obtainCompleteMessage());
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupForegroundResumeBackground() {
8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
87722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.hangupForegroundResumeBackground(obtainCompleteMessage());
8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    void hangupConnectionByIndex(CdmaCall call, int index)
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws CallStateException {
88222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int count = call.mConnections.size();
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
88422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CdmaConnection cn = (CdmaConnection)call.mConnections.get(i);
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cn.getCDMAIndex() == index) {
88622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.hangupConnection(index, obtainCompleteMessage());
8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        throw new CallStateException("no gsm index found");
8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
894cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    void hangupAllConnections(CdmaCall call) {
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
89622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            int count = call.mConnections.size();
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0; i < count; i++) {
89822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CdmaConnection cn = (CdmaConnection)call.mConnections.get(i);
89922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.hangupConnection(cn.getCDMAIndex(), obtainCompleteMessage());
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (CallStateException ex) {
902ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* package */
9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CdmaConnection getConnectionByIndex(CdmaCall call, int index)
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws CallStateException {
90922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int count = call.mConnections.size();
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
91122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CdmaConnection cn = (CdmaConnection)call.mConnections.get(i);
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (cn.getCDMAIndex() == index) {
9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return cn;
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return null;
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void flashAndSetGenericTrue() {
92122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Set generic to true because in CDMA it is not known what
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // the status of the call is after a call waiting is answered,
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 3 way call merged or a switch between calls.
92622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mForegroundCall.setGeneric(true);
92722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.notifyPreciseCallStateChanged();
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleRadioNotAvailable() {
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // handlePollCalls will clear out its
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // call list when it gets the CommandException
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // error result from this
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pollCallsWhenSafe();
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) {
93822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mCallWaitingRegistrants != null) {
93922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCallWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null));
9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleCallWaitingInfo (CdmaCallWaitingNotification cw) {
9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Check how many connections in foregroundCall.
9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If the connection in foregroundCall is more
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // than one, then the connection information is
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // not reliable anymore since it means either
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // call waiting is connected or 3 way call is
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // dialed before, so set generic.
95022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mForegroundCall.mConnections.size() > 1 ) {
95122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mForegroundCall.setGeneric(true);
9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Create a new CdmaConnection which attaches itself to ringingCall.
95522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRingingCall.setGeneric(false);
95622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        new CdmaConnection(mPhone.getContext(), cw, this, mRingingCall);
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        updatePhoneState();
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Finally notify application
9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        notifyCallWaitingInfo(cw);
9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //****** Overridden from Handler
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
964cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage (Message msg) {
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9695e2000b856a7959609e8f15148a3584ec372f865Wink Saville        if (!mPhone.mIsTheCurrentActivePhone) {
9705e2000b856a7959609e8f15148a3584ec372f865Wink Saville            Rlog.w(LOG_TAG, "Ignoring events received on inactive CdmaPhone");
9715e2000b856a7959609e8f15148a3584ec372f865Wink Saville            return;
9725e2000b856a7959609e8f15148a3584ec372f865Wink Saville        }
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_CALLS_RESULT:{
975ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
97822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if(msg == mLastRelevantPoll) {
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if(DBG_POLL) log(
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
98122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNeedsPoll = false;
98222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mLastRelevantPoll = null;
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    handlePollCalls((AsyncResult)msg.obj);
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_OPERATION_COMPLETE:
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SWITCH_RESULT:
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 // In GSM call operationComplete() here which gets the
9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 // current call list. But in CDMA there is no list so
9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                 // there is nothing to do.
9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_LAST_CALL_FAIL_CAUSE:
9990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int causeCode;
10000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
10010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                operationComplete();
10030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception != null) {
10050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // An exception occurred...just treat the disconnect
10060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // cause as "normal"
10070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode = CallFailCause.NORMAL_CLEARING;
1008ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                    Rlog.i(LOG_TAG,
10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "Exception during getLastCallFailCause, assuming normal disconnect");
10100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    causeCode = ((int[])ar.result)[0];
10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
101422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                for (int i = 0, s =  mDroppedDuringPoll.size()
10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ; i < s ; i++
10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
101722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    CdmaConnection conn = mDroppedDuringPoll.get(i);
10180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    conn.onRemoteDisconnect(causeCode);
10200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updatePhoneState();
10230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
102422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.notifyPreciseCallStateChanged();
102522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDroppedDuringPoll.clear();
10260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_REPOLL_AFTER_DELAY:
10290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CALL_STATE_CHANGE:
10300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollCallsWhenSafe();
10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_AVAILABLE:
10340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleRadioAvailable();
10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_NOT_AVAILABLE:
10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleRadioNotAvailable();
10390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_EXIT_ECM_RESPONSE_CDMA:
1042e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                // no matter the result, we still do the same here
1043e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                if (mPendingCallInEcm) {
1044e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                    mCi.dial(mPendingMO.getAddress(), mPendingCallClirMode, obtainCompleteMessage());
1045e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                    mPendingCallInEcm = false;
1046e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                }
1047e64a413b850aae224e2f56e7dfc6e0bcd667643eUma Maheswari Ramalingam                mPhone.unsetOnEcbModeExitResponse(this);
10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CALL_WAITING_INFO_CDMA:
10510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               ar = (AsyncResult)msg.obj;
10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               if (ar.exception == null) {
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                   handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result);
1054ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                   Rlog.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received");
10550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               }
10560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA:
10590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
10600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Assume 3 way call is connected
106222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingMO.onConnectedInOrOut();
106322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingMO = null;
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
10660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1067bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            case EVENT_THREE_WAY_DIAL_BLANK_FLASH:
1068bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                ar = (AsyncResult) msg.obj;
1069bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                if (ar.exception == null) {
1070bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                    postDelayed(
1071bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                            new Runnable() {
1072bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                                public void run() {
1073bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                                    if (mPendingMO != null) {
1074bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                                        mCi.sendCDMAFeatureCode(mPendingMO.getAddress(),
1075bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                                                obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
1076bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                                    }
1077bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                                }
1078bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                            }, m3WayCallFlashDelay);
1079bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                } else {
1080bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                    mPendingMO = null;
1081bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                    Rlog.w(LOG_TAG, "exception happened on Blank Flash for 3-way call");
1082bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao                }
1083bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao            break;
1084bb097a7ba08252c516e578ce30cdb658b63d7c9bJing Zhao
10850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:{
10860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville               throw new RuntimeException("unexpected event not handled");
10870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handle Ecm timer to be canceled or re-started
10930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleEcmTimer(int action) {
109522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.handleTimerInEmergencyCallbackMode(action);
10960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch(action) {
10970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CDMAPhone.CANCEL_ECM_TIMER: mIsEcmTimerCanceled = true; break;
10980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CDMAPhone.RESTART_ECM_TIMER: mIsEcmTimerCanceled = false; break;
10990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        default:
1100ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG, "handleEcmTimer, unsupported action " + action);
11010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Disable data call when emergency call is connected
11060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void disableDataCallInEmergencyCall(String dialString) {
1108f4f5308a309d43fcfca8d0d5fbb54bc38c82ca3fYorke Lee        if (PhoneNumberUtils.isLocalEmergencyNumber(mPhone.getContext(), dialString)) {
11090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("disableDataCallInEmergencyCall");
11100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mIsInEmergencyCall = true;
1111454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            mPhone.mDcTracker.setInternalDataEnabled(false);
11120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check and enable data call after an emergency call is dropped if it's
11170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * not in ECM
11180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void checkAndEnableDataCallAfterEmergencyCallDropped() {
11200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mIsInEmergencyCall) {
11210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mIsInEmergencyCall = false;
11220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
11230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) {
11240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("checkAndEnableDataCallAfterEmergencyCallDropped,inEcm=" + inEcm);
11250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (inEcm.compareTo("false") == 0) {
11270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Re-initiate data connection
1128454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville                mPhone.mDcTracker.setInternalDataEnabled(true);
11290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check the MT call to see if it's a new ring or
11350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * a unknown connection.
11360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Connection checkMtFindNewRinging(DriverCall dc, int i) {
11380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Connection newRinging = null;
11400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // it's a ringing call
114222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mConnections[i].getCall() == mRingingCall) {
114322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            newRinging = mConnections[i];
11440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (Phone.DEBUG_PHONE) log("Notify new ring " + dc);
11450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
11460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Something strange happened: a call which is neither
11470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // a ringing call nor the one we created. It could be the
11480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // call collision result from RIL
1149ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG,"Phantom call appeared " + dc);
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // If it's a connected call, set the connect time so that
11510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // it's non-zero.  It may not be accurate, but at least
11520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // it won't appear as a Missed Call.
11530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (dc.state != DriverCall.State.ALERTING
11540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && dc.state != DriverCall.State.DIALING) {
115522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mConnections[i].onConnectedInOrOut();
11569b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                if (dc.state == DriverCall.State.HOLDING) {
11579b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                    // We've transitioned into HOLDING
115822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mConnections[i].onStartedHolding();
11599b41acc443e068fa3c3e547e820f710c6e2297baUma Maheswari Ramalingam                }
11600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return newRinging;
11630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if current call is in emergency call
11670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
11680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if it is in emergency call
11690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         false if it is not in emergency call
11700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean isInEmergencyCall() {
11720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mIsInEmergencyCall;
11730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1175cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
11760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String msg) {
1177ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        Rlog.d(LOG_TAG, "[CdmaCallTracker] " + msg);
11780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
11810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("GsmCallTracker extends:");
11830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
118422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println("droppedDuringPoll: length=" + mConnections.length);
118522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for(int i=0; i < mConnections.length; i++) {
118622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            pw.printf(" mConnections[%d]=%s\n", i, mConnections[i]);
11870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
118822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mVoiceCallEndedRegistrants=" + mVoiceCallEndedRegistrants);
118922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mVoiceCallStartedRegistrants=" + mVoiceCallStartedRegistrants);
119022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCallWaitingRegistrants=" + mCallWaitingRegistrants);
119122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println("droppedDuringPoll: size=" + mDroppedDuringPoll.size());
119222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for(int i = 0; i < mDroppedDuringPoll.size(); i++) {
119322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            pw.printf( " mDroppedDuringPoll[%d]=%s\n", i, mDroppedDuringPoll.get(i));
11940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
119522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mRingingCall=" + mRingingCall);
119622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mForegroundCall=" + mForegroundCall);
119722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mBackgroundCall=" + mBackgroundCall);
119822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPendingMO=" + mPendingMO);
119922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mHangupPendingMO=" + mHangupPendingMO);
120022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPendingCallInEcm=" + mPendingCallInEcm);
12010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mIsInEmergencyCall=" + mIsInEmergencyCall);
120222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPhone=" + mPhone);
120322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDesiredMute=" + mDesiredMute);
120422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPendingCallClirMode=" + mPendingCallClirMode);
120522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mState=" + mState);
12060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mIsEcmTimerCanceled=" + mIsEcmTimerCanceled);
12070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1208b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    @Override
1209b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    public PhoneConstants.State getState() {
1210b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        return mState;
1211b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    }
12120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1213