CdmaCallTracker.java revision 22ccaf5321cf9d2df57cf0d686d1abcd74acb193
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17767a662ecde33c3979bf02b793d392aca0403162Wink Savillepackage com.android.internal.telephony.cdma;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.AsyncResult;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Registrant;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RegistrantList;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.PhoneNumberUtils;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.ServiceState;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
27dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Savilleimport android.os.SystemProperties;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.telephony.CallStateException;
30767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.CallTracker;
31767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.CommandsInterface;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.telephony.Connection;
33767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.DriverCall;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.telephony.Phone;
35dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Savilleimport com.android.internal.telephony.TelephonyProperties;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
40dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
44767a662ecde33c3979bf02b793d392aca0403162Wink Savillepublic final class CdmaCallTracker extends CallTracker {
45767a662ecde33c3979bf02b793d392aca0403162Wink Saville    static final String LOG_TAG = "CDMA";
46767a662ecde33c3979bf02b793d392aca0403162Wink Saville
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final boolean REPEAT_POLLING = false;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final boolean DBG_POLL = false;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Constants
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
53767a662ecde33c3979bf02b793d392aca0403162Wink Saville    static final int MAX_CONNECTIONS = 1;   // only 1 connection allowed in CDMA
54767a662ecde33c3979bf02b793d392aca0403162Wink Saville    static final int MAX_CONNECTIONS_PER_CALL = 1; // only 1 connection allowed per call
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Instance Variables
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
58767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaConnection connections[] = new CdmaConnection[MAX_CONNECTIONS];
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    RegistrantList voiceCallEndedRegistrants = new RegistrantList();
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    RegistrantList voiceCallStartedRegistrants = new RegistrantList();
6122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    RegistrantList callWaitingRegistrants =  new RegistrantList();
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // connections dropped durin last poll
65767a662ecde33c3979bf02b793d392aca0403162Wink Saville    ArrayList<CdmaConnection> droppedDuringPoll
66767a662ecde33c3979bf02b793d392aca0403162Wink Saville        = new ArrayList<CdmaConnection>(MAX_CONNECTIONS);
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
68767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaCall ringingCall = new CdmaCall(this);
69767a662ecde33c3979bf02b793d392aca0403162Wink Saville    // A call that is ringing or (call) waiting
70767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaCall foregroundCall = new CdmaCall(this);
71767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaCall backgroundCall = new CdmaCall(this);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
73767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaConnection pendingMO;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean hangupPendingMO;
75dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    boolean pendingCallInECM=false;
76767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CDMAPhone phone;
77767a662ecde33c3979bf02b793d392aca0403162Wink Saville
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean desiredMute = false;    // false = mute off
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
80dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    int pendingCallClirMode;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Phone.State state = Phone.State.IDLE;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
84767a662ecde33c3979bf02b793d392aca0403162Wink Saville//    boolean needsPoll;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
88767a662ecde33c3979bf02b793d392aca0403162Wink Saville    //***** Events
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Constructors
91767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaCallTracker(CDMAPhone phone) {
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.phone = phone;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm = phone.mCM;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
9722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        cm.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null);
9822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        foregroundCall.setGeneric(false);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
101767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void dispose() {
102767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForCallStateChanged(this);
103767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForOn(this);
104767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForNotAvailable(this);
10522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        cm.unregisterForCallWaitingInfo(this);
106767a662ecde33c3979bf02b793d392aca0403162Wink Saville        for(CdmaConnection c : connections) {
107767a662ecde33c3979bf02b793d392aca0403162Wink Saville            try {
108767a662ecde33c3979bf02b793d392aca0403162Wink Saville                if(c != null) hangup(c);
109767a662ecde33c3979bf02b793d392aca0403162Wink Saville            } catch (CallStateException ex) {
110767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.e(LOG_TAG, "unexpected error on hangup during dispose");
111767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
112767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
113767a662ecde33c3979bf02b793d392aca0403162Wink Saville
114767a662ecde33c3979bf02b793d392aca0403162Wink Saville        try {
115767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if(pendingMO != null) hangup(pendingMO);
116767a662ecde33c3979bf02b793d392aca0403162Wink Saville        } catch (CallStateException ex) {
117767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.e(LOG_TAG, "unexpected error on hangup during dispose");
118767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
119767a662ecde33c3979bf02b793d392aca0403162Wink Saville
120767a662ecde33c3979bf02b793d392aca0403162Wink Saville        clearDisconnected();
121767a662ecde33c3979bf02b793d392aca0403162Wink Saville
122767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
123767a662ecde33c3979bf02b793d392aca0403162Wink Saville
124dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    @Override
125767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void finalize() {
126767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Log.d(LOG_TAG, "CdmaCallTracker finalized");
127767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
128767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Instance Methods
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Public Methods
132767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Registrant r = new Registrant(h, what, obj);
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        voiceCallStartedRegistrants.add(r);
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
136767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void unregisterForVoiceCallStarted(Handler h) {
137767a662ecde33c3979bf02b793d392aca0403162Wink Saville        voiceCallStartedRegistrants.remove(h);
138767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
140767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Registrant r = new Registrant(h, what, obj);
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        voiceCallEndedRegistrants.add(r);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
145767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void unregisterForVoiceCallEnded(Handler h) {
146767a662ecde33c3979bf02b793d392aca0403162Wink Saville        voiceCallEndedRegistrants.remove(h);
147767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
148767a662ecde33c3979bf02b793d392aca0403162Wink Saville
14922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    public void registerForCallWaiting(Handler h, int what, Object obj) {
15022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        Registrant r = new Registrant (h, what, obj);
15122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        callWaitingRegistrants.add(r);
15222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
15322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
15422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    public void unregisterForCallWaiting(Handler h) {
15522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        callWaitingRegistrants.remove(h);
15622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
15722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
159767a662ecde33c3979bf02b793d392aca0403162Wink Saville    fakeHoldForegroundBeforeDial() {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        List<Connection> connCopy;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We need to make a copy here, since fakeHoldBeforeDial()
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // modifies the lists, and we don't want to reverse the order
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        connCopy = (List<Connection>) foregroundCall.connections.clone();
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0, s = connCopy.size() ; i < s ; i++) {
167767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CdmaConnection conn = (CdmaConnection)connCopy.get(i);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conn.fakeHoldBeforeDial();
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clirMode is one of the CLIR_ constants
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Connection
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dial (String dialString, int clirMode) throws CallStateException {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // note that this triggers call state changed notif
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        clearDisconnected();
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!canDial()) {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException("cannot dial in current state");
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
18622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // We are initiating a call therefore even if we previously
18722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // didn't know the state (i.e. Generic was true) we now know
18822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // and therefore can set Generic to false.
18922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        foregroundCall.setGeneric(false);
19022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The new call must be assigned to the foreground call.
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // That call must be idle, so place anything that's
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // there on hold
194767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (foregroundCall.getState() == CdmaCall.State.ACTIVE) {
19522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            return dialThreeWay(dialString);
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
198767a662ecde33c3979bf02b793d392aca0403162Wink Saville        pendingMO = new CdmaConnection(phone.getContext(), dialString, this, foregroundCall);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        hangupPendingMO = false;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pendingMO.address == null || pendingMO.address.length() == 0
20222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0) {
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Phone number is invalid
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // handlePollCalls() will notice this call not present
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // and will mark it as dropped.
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pollCallsWhenSafe();
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Always unmute when initiating a new call
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setMute(false);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
213dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
214dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            if(inEcm.equals("false")) {
215dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
216dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            } else {
217dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                phone.exitEmergencyCallbackMode();
218dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                phone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
219dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                pendingCallClirMode=clirMode;
220dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                pendingCallInECM=true;
221dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updatePhoneState();
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        phone.notifyCallStateChanged();
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return pendingMO;
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Connection
232767a662ecde33c3979bf02b793d392aca0403162Wink Saville    dial (String dialString) throws CallStateException {
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return dial(dialString, CommandsInterface.CLIR_DEFAULT);
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    private Connection
23722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    dialThreeWay (String dialString) {
23822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        if (!foregroundCall.isIdle()) {
23922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // Attach the new connection to foregroundCall
24022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            pendingMO = new CdmaConnection(phone.getContext(),
24122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                                dialString, this, foregroundCall);
24222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            cm.sendCDMAFeatureCode(pendingMO.address,
24322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
24422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            return pendingMO;
24522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        }
24622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        return null;
24722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    void
25022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    acceptCall() throws CallStateException {
251767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (ringingCall.getState() == CdmaCall.State.INCOMING) {
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.i("phone", "acceptCall: incoming...");
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Always unmute when answering a new call
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setMute(false);
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.acceptCall(obtainCompleteMessage());
25622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        } else if ((foregroundCall.connections.size() > 0) &&
25722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                   (ringingCall.getState() == CdmaCall.State.WAITING)) {
25822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // TODO(Moto): jsh asks, "Is this check necessary? I don't think it should be
25922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // possible to have no fg connection and a WAITING call, but if we should hit
26022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // this situation, is a CallStateExcetion appropriate?"
26122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            CdmaConnection cwConn = (CdmaConnection)(ringingCall.getLatestConnection());
26222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
26322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // Since there is no network response for supplimentary
26422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // service for CDMA, we assume call waiting is answered.
26522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // ringing Call state change to idle is in CdmaCall.detach
26622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // triggered by updateParent.
26722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            cwConn.updateParent(ringingCall, foregroundCall);
26822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            cwConn.onConnectedInOrOut();
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switchWaitingOrHoldingAndActive();
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException("phone not ringing");
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
276767a662ecde33c3979bf02b793d392aca0403162Wink Saville    rejectCall () throws CallStateException {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // AT+CHLD=0 means "release held or UDUB"
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // so if the phone isn't ringing, this could hang up held
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ringingCall.getState().isRinging()) {
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.rejectCall(obtainCompleteMessage());
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException("phone not ringing");
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switchWaitingOrHoldingAndActive() throws CallStateException {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Should we bother with this check?
289767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (ringingCall.getState() == CdmaCall.State.INCOMING) {
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException("cannot be in the incoming state");
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
29222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            flashAndSetGenericTrue();
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
297767a662ecde33c3979bf02b793d392aca0403162Wink Saville    conference() throws CallStateException {
29822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Should we be checking state?
29922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        flashAndSetGenericTrue();
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
303767a662ecde33c3979bf02b793d392aca0403162Wink Saville    explicitCallTransfer() throws CallStateException {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
308767a662ecde33c3979bf02b793d392aca0403162Wink Saville    clearDisconnected() {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        internalClearDisconnected();
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updatePhoneState();
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        phone.notifyCallStateChanged();
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean
316767a662ecde33c3979bf02b793d392aca0403162Wink Saville    canConference() {
317767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return foregroundCall.getState() == CdmaCall.State.ACTIVE
318767a662ecde33c3979bf02b793d392aca0403162Wink Saville                && backgroundCall.getState() == CdmaCall.State.HOLDING
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && !backgroundCall.isFull()
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && !foregroundCall.isFull();
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean
324767a662ecde33c3979bf02b793d392aca0403162Wink Saville    canDial() {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean ret;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int serviceState = phone.getServiceState().getState();
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ret = (serviceState != ServiceState.STATE_POWER_OFF) &&
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pendingMO == null
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && !ringingCall.isRinging()
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && (!foregroundCall.getState().isAlive()
33222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                || (foregroundCall.getState() == CdmaCall.State.ACTIVE)
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || !backgroundCall.getState().isAlive());
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ret;
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean
339767a662ecde33c3979bf02b793d392aca0403162Wink Saville    canTransfer() {
340767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
341767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return false;
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Private Instance Methods
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
347767a662ecde33c3979bf02b793d392aca0403162Wink Saville    internalClearDisconnected() {
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ringingCall.clearDisconnected();
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        foregroundCall.clearDisconnected();
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        backgroundCall.clearDisconnected();
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Obtain a message to use for signalling "invoke getCurrentCalls() when
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this operation and all other pending operations are complete
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Message
358767a662ecde33c3979bf02b793d392aca0403162Wink Saville    obtainCompleteMessage() {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Obtain a message to use for signalling "invoke getCurrentCalls() when
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this operation and all other pending operations are complete
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Message
367767a662ecde33c3979bf02b793d392aca0403162Wink Saville    obtainCompleteMessage(int what) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pendingOperations++;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lastRelevantPoll = null;
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        needsPoll = true;
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pendingOperations + ", needsPoll=" + needsPoll);
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return obtainMessage(what);
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
379767a662ecde33c3979bf02b793d392aca0403162Wink Saville    operationComplete() {
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pendingOperations--;
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG_POLL) log("operationComplete: pendingOperations=" +
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pendingOperations + ", needsPoll=" + needsPoll);
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pendingOperations == 0 && needsPoll) {
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.getCurrentCalls(lastRelevantPoll);
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (pendingOperations < 0) {
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // this should never happen
390767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.e(LOG_TAG,"CdmaCallTracker.pendingOperations < 0");
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pendingOperations = 0;
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
398767a662ecde33c3979bf02b793d392aca0403162Wink Saville    updatePhoneState() {
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Phone.State oldState = state;
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ringingCall.isRinging()) {
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = Phone.State.RINGING;
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (pendingMO != null ||
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                !(foregroundCall.isIdle() && backgroundCall.isIdle())) {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = Phone.State.OFFHOOK;
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = Phone.State.IDLE;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (state == Phone.State.IDLE && oldState != state) {
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            voiceCallEndedRegistrants.notifyRegistrants(
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                new AsyncResult(null, null, null));
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (oldState == Phone.State.IDLE && oldState != state) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            voiceCallStartedRegistrants.notifyRegistrants (
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    new AsyncResult(null, null, null));
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (state != oldState) {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.notifyPhoneStateChanged();
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
423767a662ecde33c3979bf02b793d392aca0403162Wink Saville    // ***** Overwritten from CallTracker
424767a662ecde33c3979bf02b793d392aca0403162Wink Saville
425767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void
426767a662ecde33c3979bf02b793d392aca0403162Wink Saville    handlePollCalls(AsyncResult ar) {
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        List polledCalls;
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ar.exception == null) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            polledCalls = (List)ar.result;
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // just a dummy empty ArrayList to cause the loop
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to hang up all the calls
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            polledCalls = new ArrayList();
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Radio probably wasn't ready--try again in a bit
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // But don't keep polling if the channel is closed
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pollCallsAfterDelay();
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Connection newRinging = null; //or waiting
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasNonHangupStateChanged = false;   // Any change besides
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    // a dropped connection
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean needsPollDelay = false;
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean unknownConnectionAppeared = false;
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0, curDC = 0, dcSize = polledCalls.size()
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ; i < connections.length; i++) {
450767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CdmaConnection conn = connections[i];
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            DriverCall dc = null;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // polledCall list is sparse
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (curDC < dcSize) {
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dc = (DriverCall) polledCalls.get(curDC);
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (dc.index == i+1) {
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curDC++;
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    dc = null;
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    conn+", dc=" + dc);
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (conn == null && dc != null) {
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Connection appeared in CLCC response that we don't know about
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (pendingMO != null && pendingMO.compareTo(dc)) {
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (DBG_POLL) log("poll: pendingMO=" + pendingMO);
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // It's our pending mobile originating call
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    connections[i] = pendingMO;
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    pendingMO.index = i;
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    pendingMO.update(dc);
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    pendingMO = null;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Someone has already asked to hangup this call
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (hangupPendingMO) {
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hangupPendingMO = false;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (Phone.DEBUG_PHONE) log(
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "poll: hangupPendingMO, hangup conn " + i);
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hangup(connections[i]);
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (CallStateException ex) {
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            Log.e(LOG_TAG, "unexpected error on hangup");
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Do not continue processing this poll
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Wait for hangup and repoll
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return;
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
495767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    connections[i] = new CdmaConnection(phone.getContext(), dc, this, i);
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // it's a ringing call
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (connections[i].getCall() == ringingCall) {
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        newRinging = connections[i];
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Something strange happened: a call appeared
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // which is neither a ringing call or one we created.
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Either we've crashed and re-attached to an existing
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // call, or something else (eg, SIM) initiated the call.
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        Log.i(LOG_TAG,"Phantom call appeared " + dc);
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // If it's a connected call, set the connect time so that
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // it's non-zero.  It may not be accurate, but at least
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // it won't appear as a Missed Call.
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (dc.state != DriverCall.State.ALERTING
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                && dc.state != DriverCall.State.DIALING) {
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            connections[i].connectTime = System.currentTimeMillis();
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        unknownConnectionAppeared = true;
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasNonHangupStateChanged = true;
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (conn != null && dc == null) {
52122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                int count = foregroundCall.connections.size();
52222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                if (count == 0) {
52322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // Handle an unanswered MO/MT call, there is no
52422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // foregroundCall connections at this time.
52522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    droppedDuringPoll.add(conn);
52622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                } else {
52722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // Loop through foreground call connections as
52822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // it contains the known logical connections.
52922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    for (int n = 0; n < count; n++) {
53022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                        CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n);
53122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                        droppedDuringPoll.add(cn);
53222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    }
53322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // TODO(Moto): jsh asks, "Are we sure we don't need to do this for
53422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // ringingCall as well? What if there's a WAITING call (ie, UI timer
53522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // hasn't expired, moving it to DISCONNECTED)? How/when will it
53622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // transition to DISCONNECTED?"
53722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                }
53822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                foregroundCall.setGeneric(false);
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Dropped connections are removed from the CallTracker
540767a662ecde33c3979bf02b793d392aca0403162Wink Saville                // list but kept in the Call list
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                connections[i] = null;
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (conn != null && dc != null && !conn.compareTo(dc)) {
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Connection in CLCC response does not match what
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // we were tracking. Assume dropped call and new call
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                droppedDuringPoll.add(conn);
547767a662ecde33c3979bf02b793d392aca0403162Wink Saville                connections[i] = new CdmaConnection (phone.getContext(), dc, this, i);
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (connections[i].getCall() == ringingCall) {
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newRinging = connections[i];
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } // else something strange happened
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasNonHangupStateChanged = true;
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                boolean changed;
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                changed = conn.update(dc);
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (REPEAT_POLLING) {
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (dc != null) {
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // FIXME with RIL, we should not need this anymore
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((dc.state == DriverCall.State.DIALING
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || (dc.state == DriverCall.State.ALERTING
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || (dc.state == DriverCall.State.INCOMING
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || (dc.state == DriverCall.State.WAITING
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ) {
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Sometimes there's no unsolicited notification
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // for state transitions
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        needsPollDelay = true;
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // This is the first poll after an ATD.
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We expect the pending call to appear in the list
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If it does not, we land here
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pendingMO != null) {
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + foregroundCall.getState());
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            droppedDuringPoll.add(pendingMO);
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pendingMO = null;
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hangupPendingMO = false;
589dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            if( pendingCallInECM) {
590dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                pendingCallInECM = false;
591dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newRinging != null) {
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.notifyNewRingingConnection(newRinging);
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // clear the "local hangup" and "missed/rejected call"
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // cases from the "dropped during poll" list
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // These cases need no "last call fail" reason
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) {
602767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CdmaConnection conn = droppedDuringPoll.get(i);
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (conn.isIncoming() && conn.getConnectTime() == 0) {
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Missed or rejected call
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Connection.DisconnectCause cause;
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (conn.cause == Connection.DisconnectCause.LOCAL) {
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    cause = Connection.DisconnectCause.INCOMING_REJECTED;
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    cause = Connection.DisconnectCause.INCOMING_MISSED;
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Phone.DEBUG_PHONE) {
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    log("missed/rejected call, conn.cause=" + conn.cause);
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    log("setting cause to " + cause);
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                droppedDuringPoll.remove(i);
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                conn.onDisconnect(cause);
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (conn.cause == Connection.DisconnectCause.LOCAL) {
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Local hangup
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                droppedDuringPoll.remove(i);
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                conn.onDisconnect(Connection.DisconnectCause.LOCAL);
623767a662ecde33c3979bf02b793d392aca0403162Wink Saville            } else if (conn.cause == Connection.DisconnectCause.INVALID_NUMBER) {
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                droppedDuringPoll.remove(i);
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER);
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Any non-local disconnects: determine cause
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (droppedDuringPoll.size() > 0) {
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.getLastCallFailCause(
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (needsPollDelay) {
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pollCallsAfterDelay();
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Cases when we can no longer keep disconnected Connection's
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // with their previous calls
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // 1) the phone has started to ring
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // 2) A Call/Connection object has changed state...
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //    we may have switched or held or answered (but not hung up)
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newRinging != null || hasNonHangupStateChanged) {
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            internalClearDisconnected();
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updatePhoneState();
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (unknownConnectionAppeared) {
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.notifyUnknownConnection();
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasNonHangupStateChanged || newRinging != null) {
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.notifyCallStateChanged();
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //dumpState();
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
661767a662ecde33c3979bf02b793d392aca0403162Wink Saville    //***** Called from CdmaConnection
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ void
663767a662ecde33c3979bf02b793d392aca0403162Wink Saville    hangup (CdmaConnection conn) throws CallStateException {
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (conn.owner != this) {
665767a662ecde33c3979bf02b793d392aca0403162Wink Saville            throw new CallStateException ("CdmaConnection " + conn
666767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                    + "does not belong to CdmaCallTracker " + this);
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (conn == pendingMO) {
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We're hanging up an outgoing call that doesn't have it's
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // GSM index assigned yet
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hangupPendingMO = true;
67522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        } else if ((conn.getCall() == ringingCall)
67622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                && (ringingCall.getState() == CdmaCall.State.WAITING)) {
67722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // Handle call waiting hang up case.
67822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            //
67922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // The ringingCall state will change to IDLE in CdmaCall.detach
68022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // if the ringing call connection size is 0. We don't specifically
68122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // set the ringing call state to IDLE here to avoid a race condition
68222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // where a new call waiting could get a hang up from an old call
68322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // waiting ringingCall.
68422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // TODO(Moto): jsh asks, "Should we call conn.ondisconnect() here or Somewhere?"
68522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            ringingCall.detach(conn);
68622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            return;
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
689767a662ecde33c3979bf02b793d392aca0403162Wink Saville                cm.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage());
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (CallStateException ex) {
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Ignore "connection not found"
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Call may have hung up already
693767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.w(LOG_TAG,"CdmaCallTracker WARN: hangup() on absent connection "
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                + conn);
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        conn.onHangupLocal();
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ void
702767a662ecde33c3979bf02b793d392aca0403162Wink Saville    separate (CdmaConnection conn) throws CallStateException {
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (conn.owner != this) {
704767a662ecde33c3979bf02b793d392aca0403162Wink Saville            throw new CallStateException ("CdmaConnection " + conn
705767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                    + "does not belong to CdmaCallTracker " + this);
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
708767a662ecde33c3979bf02b793d392aca0403162Wink Saville            cm.separateConnection (conn.getCDMAIndex(),
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                obtainCompleteMessage(EVENT_SEPARATE_RESULT));
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (CallStateException ex) {
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Ignore "connection not found"
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Call may have hung up already
713767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.w(LOG_TAG,"CdmaCallTracker WARN: separate() on absent connection "
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          + conn);
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
718767a662ecde33c3979bf02b793d392aca0403162Wink Saville    //***** Called from CDMAPhone
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ void
721767a662ecde33c3979bf02b793d392aca0403162Wink Saville    setMute(boolean mute) {
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        desiredMute = mute;
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.setMute(desiredMute, null);
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ boolean
727767a662ecde33c3979bf02b793d392aca0403162Wink Saville    getMute() {
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return desiredMute;
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
732767a662ecde33c3979bf02b793d392aca0403162Wink Saville    //***** Called from CdmaCall
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */ void
735767a662ecde33c3979bf02b793d392aca0403162Wink Saville    hangup (CdmaCall call) throws CallStateException {
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (call.getConnections().size() == 0) {
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException("no connections in call");
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (call == ringingCall) {
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.hangupWaitingOrBackground(obtainCompleteMessage());
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (call == foregroundCall) {
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (call.isDialingOrAlerting()) {
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Phone.DEBUG_PHONE) {
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    log("(foregnd) hangup dialing or alerting...");
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
748767a662ecde33c3979bf02b793d392aca0403162Wink Saville                hangup((CdmaConnection)(call.getConnections().get(0)));
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hangupForegroundResumeBackground();
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (call == backgroundCall) {
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ringingCall.isRinging()) {
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Phone.DEBUG_PHONE) {
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    log("hangup all conns in background call");
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hangupAllConnections(call);
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hangupWaitingOrBackground();
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
762767a662ecde33c3979bf02b793d392aca0403162Wink Saville            throw new RuntimeException ("CdmaCall " + call +
763767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    "does not belong to CdmaCallTracker " + this);
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        call.onHangupLocal();
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void hangupWaitingOrBackground() {
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.hangupWaitingOrBackground(obtainCompleteMessage());
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void hangupForegroundResumeBackground() {
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.hangupForegroundResumeBackground(obtainCompleteMessage());
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
781767a662ecde33c3979bf02b793d392aca0403162Wink Saville    void hangupConnectionByIndex(CdmaCall call, int index)
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws CallStateException {
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = call.connections.size();
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
785767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CdmaConnection cn = (CdmaConnection)call.connections.get(i);
786767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (cn.getCDMAIndex() == index) {
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm.hangupConnection(index, obtainCompleteMessage());
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw new CallStateException("no gsm index found");
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
795767a662ecde33c3979bf02b793d392aca0403162Wink Saville    void hangupAllConnections(CdmaCall call) throws CallStateException{
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int count = call.connections.size();
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
799767a662ecde33c3979bf02b793d392aca0403162Wink Saville                CdmaConnection cn = (CdmaConnection)call.connections.get(i);
800767a662ecde33c3979bf02b793d392aca0403162Wink Saville                cm.hangupConnection(cn.getCDMAIndex(), obtainCompleteMessage());
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (CallStateException ex) {
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */
808767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaConnection getConnectionByIndex(CdmaCall call, int index)
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws CallStateException {
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = call.connections.size();
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
812767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CdmaConnection cn = (CdmaConnection)call.connections.get(i);
813767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (cn.getCDMAIndex() == index) {
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return cn;
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
82122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    private void flashAndSetGenericTrue() throws CallStateException {
82222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
82322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
82422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Set generic to true because in CDMA it is not known what
82522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // the status of the call is after a call waiting is answered,
82622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // 3 way call merged or a switch between calls.
82722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        foregroundCall.setGeneric(true);
82822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        phone.notifyCallStateChanged();
82922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
83022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Phone.SuppService getFailedService(int what) {
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (what) {
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SWITCH_RESULT:
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return Phone.SuppService.SWITCH;
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_CONFERENCE_RESULT:
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return Phone.SuppService.CONFERENCE;
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SEPARATE_RESULT:
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return Phone.SuppService.SEPARATE;
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_ECT_RESULT:
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return Phone.SuppService.TRANSFER;
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Phone.SuppService.UNKNOWN;
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
845767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private void handleRadioNotAvailable() {
846767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // handlePollCalls will clear out its
847767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // call list when it gets the CommandException
848767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // error result from this
849767a662ecde33c3979bf02b793d392aca0403162Wink Saville        pollCallsWhenSafe();
850767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
851767a662ecde33c3979bf02b793d392aca0403162Wink Saville
85222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) {
85322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        if (callWaitingRegistrants != null) {
85422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            callWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null));
85522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        }
85622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
85722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
85822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    private void handleCallWaitingInfo (CdmaCallWaitingNotification cw) {
85922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Check how many connections in foregroundCall.
86022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // If the connection in foregroundCall is more
86122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // than one, then the connection information is
86222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // not reliable anymore since it means either
86322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // call waiting is connected or 3 way call is
86422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // dialed before, so set generic.
86522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        if (foregroundCall.connections.size() > 1 ) {
86622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            foregroundCall.setGeneric(true);
86722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        }
86822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
86922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Create a new CdmaConnection which attaches itself to ringingCall.
87022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        ringingCall.setGeneric(false);
87122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        new CdmaConnection(phone.getContext(), cw, this, ringingCall);
87222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
87322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Finally notify application
87422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        notifyCallWaitingInfo(cw);
87522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //****** Overridden from Handler
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void
879767a662ecde33c3979bf02b793d392aca0403162Wink Saville    handleMessage (Message msg) {
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AsyncResult ar;
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (msg.what) {
883767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case EVENT_POLL_CALLS_RESULT:{
884767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult)msg.obj;
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
887767a662ecde33c3979bf02b793d392aca0403162Wink Saville                if(msg == lastRelevantPoll) {
888767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    if(DBG_POLL) log(
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    needsPoll = false;
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    lastRelevantPoll = null;
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handlePollCalls((AsyncResult)msg.obj);
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
894767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_OPERATION_COMPLETE:
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                operationComplete();
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SWITCH_RESULT:
90222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                 // In GSM call operationComplete() here which gets the
90322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                 // current call list. But in CDMA there is no list so
90422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                 // there is nothing to do.
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_GET_LAST_CALL_FAIL_CAUSE:
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int causeCode;
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult)msg.obj;
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                operationComplete();
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (ar.exception != null) {
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // An exception occurred...just treat the disconnect
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // cause as "normal"
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    causeCode = CallFailCause.NORMAL_CLEARING;
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.i(LOG_TAG,
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "Exception during getLastCallFailCause, assuming normal disconnect");
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    causeCode = ((int[])ar.result)[0];
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i = 0, s =  droppedDuringPoll.size()
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ; i < s ; i++
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ) {
926767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    CdmaConnection conn = droppedDuringPoll.get(i);
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    conn.onRemoteDisconnect(causeCode);
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                updatePhoneState();
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                phone.notifyCallStateChanged();
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                droppedDuringPoll.clear();
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_CALL_STATE_CHANGE:
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollCallsWhenSafe();
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_RADIO_AVAILABLE:
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                handleRadioAvailable();
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_RADIO_NOT_AVAILABLE:
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                handleRadioNotAvailable();
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
948767a662ecde33c3979bf02b793d392aca0403162Wink Saville
949dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            case EVENT_EXIT_ECM_RESPONSE_CDMA:
950dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville               //no matter the result, we still do the same here
951dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville               if (pendingCallInECM) {
952dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                   cm.dial(pendingMO.address, pendingCallClirMode, obtainCompleteMessage());
953dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                   pendingCallInECM = false;
954dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville               }
955dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville               phone.unsetOnEcbModeExitResponse(this);
956dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            break;
957dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
95822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            case EVENT_CALL_WAITING_INFO_CDMA:
95922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville               ar = (AsyncResult)msg.obj;
96022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville               if (ar.exception == null) {
96122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                   handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result);
96222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                   Log.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received");
96322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville               }
96422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            break;
96522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
96622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA:
96722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                ar = (AsyncResult)msg.obj;
96822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                if (ar.exception == null) {
96922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // Assume 3 way call is connected
97022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    pendingMO.onConnectedInOrOut();
97122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                }
97222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            break;
97322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
974767a662ecde33c3979bf02b793d392aca0403162Wink Saville            default:{
975dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville               throw new RuntimeException("unexpected event not handled");
976767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
980767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void log(String msg) {
981767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Log.d(LOG_TAG, "[CdmaCallTracker] " + msg);
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
983767a662ecde33c3979bf02b793d392aca0403162Wink Saville
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
985