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
64390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby    // connections dropped during 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;
7595a1d1a89e383dab893750638c2393dec54833ffWink Saville    boolean pendingCallInEcm=false;
761cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang    boolean mIsInEmergencyCall = false;
77767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CDMAPhone phone;
78767a662ecde33c3979bf02b793d392aca0403162Wink Saville
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean desiredMute = false;    // false = mute off
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
81dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    int pendingCallClirMode;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Phone.State state = Phone.State.IDLE;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8495a1d1a89e383dab893750638c2393dec54833ffWink Saville    private boolean mIsEcmTimerCanceled = false;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
86767a662ecde33c3979bf02b793d392aca0403162Wink Saville//    boolean needsPoll;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
90767a662ecde33c3979bf02b793d392aca0403162Wink Saville    //***** Events
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Constructors
93767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaCallTracker(CDMAPhone phone) {
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.phone = phone;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm = phone.mCM;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
9922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        cm.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null);
10022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        foregroundCall.setGeneric(false);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
103767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void dispose() {
104767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForCallStateChanged(this);
105767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForOn(this);
106767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForNotAvailable(this);
10722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        cm.unregisterForCallWaitingInfo(this);
108767a662ecde33c3979bf02b793d392aca0403162Wink Saville        for(CdmaConnection c : connections) {
109767a662ecde33c3979bf02b793d392aca0403162Wink Saville            try {
110767a662ecde33c3979bf02b793d392aca0403162Wink Saville                if(c != null) hangup(c);
111767a662ecde33c3979bf02b793d392aca0403162Wink Saville            } catch (CallStateException ex) {
112767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.e(LOG_TAG, "unexpected error on hangup during dispose");
113767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
114767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
115767a662ecde33c3979bf02b793d392aca0403162Wink Saville
116767a662ecde33c3979bf02b793d392aca0403162Wink Saville        try {
117767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if(pendingMO != null) hangup(pendingMO);
118767a662ecde33c3979bf02b793d392aca0403162Wink Saville        } catch (CallStateException ex) {
119767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.e(LOG_TAG, "unexpected error on hangup during dispose");
120767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
121767a662ecde33c3979bf02b793d392aca0403162Wink Saville
122767a662ecde33c3979bf02b793d392aca0403162Wink Saville        clearDisconnected();
123767a662ecde33c3979bf02b793d392aca0403162Wink Saville
124767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
125767a662ecde33c3979bf02b793d392aca0403162Wink Saville
126dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    @Override
127767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void finalize() {
128767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Log.d(LOG_TAG, "CdmaCallTracker finalized");
129767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
130767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Instance Methods
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Public Methods
134767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Registrant r = new Registrant(h, what, obj);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        voiceCallStartedRegistrants.add(r);
1379d7d62801ddb206d2ea96d74864a9edfe54d2eeeWink Saville        // Notify if in call when registering
1389d7d62801ddb206d2ea96d74864a9edfe54d2eeeWink Saville        if (state != Phone.State.IDLE) {
1399d7d62801ddb206d2ea96d74864a9edfe54d2eeeWink Saville            r.notifyRegistrant(new AsyncResult(null, null, null));
1409d7d62801ddb206d2ea96d74864a9edfe54d2eeeWink Saville        }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
142767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void unregisterForVoiceCallStarted(Handler h) {
143767a662ecde33c3979bf02b793d392aca0403162Wink Saville        voiceCallStartedRegistrants.remove(h);
144767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
146767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Registrant r = new Registrant(h, what, obj);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        voiceCallEndedRegistrants.add(r);
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
151767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void unregisterForVoiceCallEnded(Handler h) {
152767a662ecde33c3979bf02b793d392aca0403162Wink Saville        voiceCallEndedRegistrants.remove(h);
153767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
154767a662ecde33c3979bf02b793d392aca0403162Wink Saville
15522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    public void registerForCallWaiting(Handler h, int what, Object obj) {
15622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        Registrant r = new Registrant (h, what, obj);
15722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        callWaitingRegistrants.add(r);
15822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
15922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
16022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    public void unregisterForCallWaiting(Handler h) {
16122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        callWaitingRegistrants.remove(h);
16222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
16322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
165767a662ecde33c3979bf02b793d392aca0403162Wink Saville    fakeHoldForegroundBeforeDial() {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        List<Connection> connCopy;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We need to make a copy here, since fakeHoldBeforeDial()
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // modifies the lists, and we don't want to reverse the order
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        connCopy = (List<Connection>) foregroundCall.connections.clone();
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0, s = connCopy.size() ; i < s ; i++) {
173767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CdmaConnection conn = (CdmaConnection)connCopy.get(i);
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conn.fakeHoldBeforeDial();
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clirMode is one of the CLIR_ constants
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Connection
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dial (String dialString, int clirMode) throws CallStateException {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // note that this triggers call state changed notif
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        clearDisconnected();
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!canDial()) {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException("cannot dial in current state");
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19195a1d1a89e383dab893750638c2393dec54833ffWink Saville        String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
19295a1d1a89e383dab893750638c2393dec54833ffWink Saville        boolean isPhoneInEcmMode = inEcm.equals("true");
1936b7c3f8a1cd8b638defc28a3249746e99b8039aeShaopeng Jia        boolean isEmergencyCall =
1946b7c3f8a1cd8b638defc28a3249746e99b8039aeShaopeng Jia                PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext());
19595a1d1a89e383dab893750638c2393dec54833ffWink Saville
19695a1d1a89e383dab893750638c2393dec54833ffWink Saville        // Cancel Ecm timer if a second emergency call is originating in Ecm mode
19795a1d1a89e383dab893750638c2393dec54833ffWink Saville        if (isPhoneInEcmMode && isEmergencyCall) {
19895a1d1a89e383dab893750638c2393dec54833ffWink Saville            handleEcmTimer(phone.CANCEL_ECM_TIMER);
19995a1d1a89e383dab893750638c2393dec54833ffWink Saville        }
20022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
20122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // We are initiating a call therefore even if we previously
20222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // didn't know the state (i.e. Generic was true) we now know
20322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // and therefore can set Generic to false.
20422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        foregroundCall.setGeneric(false);
20522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The new call must be assigned to the foreground call.
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // That call must be idle, so place anything that's
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // there on hold
209767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (foregroundCall.getState() == CdmaCall.State.ACTIVE) {
21022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            return dialThreeWay(dialString);
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
213767a662ecde33c3979bf02b793d392aca0403162Wink Saville        pendingMO = new CdmaConnection(phone.getContext(), dialString, this, foregroundCall);
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        hangupPendingMO = false;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pendingMO.address == null || pendingMO.address.length() == 0
21722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0) {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Phone number is invalid
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // handlePollCalls() will notice this call not present
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // and will mark it as dropped.
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pollCallsWhenSafe();
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Always unmute when initiating a new call
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setMute(false);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2281cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang            // Check data call
2291cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang            disableDataCallInEmergencyCall(dialString);
2301cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang
23195a1d1a89e383dab893750638c2393dec54833ffWink Saville            // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
23295a1d1a89e383dab893750638c2393dec54833ffWink Saville            if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
233dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
234dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            } else {
235dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                phone.exitEmergencyCallbackMode();
236dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                phone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
237dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                pendingCallClirMode=clirMode;
23895a1d1a89e383dab893750638c2393dec54833ffWink Saville                pendingCallInEcm=true;
239dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updatePhoneState();
2431c42769339d8fe98ecb2698c64e7dc6672e3d59dJaikumar Ganesh        phone.notifyPreciseCallStateChanged();
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return pendingMO;
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Connection
250767a662ecde33c3979bf02b793d392aca0403162Wink Saville    dial (String dialString) throws CallStateException {
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return dial(dialString, CommandsInterface.CLIR_DEFAULT);
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    private Connection
25522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    dialThreeWay (String dialString) {
25622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        if (!foregroundCall.isIdle()) {
2571cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang            // Check data call
2581cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang            disableDataCallInEmergencyCall(dialString);
2591cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang
26022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // Attach the new connection to foregroundCall
26122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            pendingMO = new CdmaConnection(phone.getContext(),
26222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                                dialString, this, foregroundCall);
26322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            cm.sendCDMAFeatureCode(pendingMO.address,
26422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
26522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            return pendingMO;
26622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        }
26722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        return null;
26822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    void
27122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    acceptCall() throws CallStateException {
272767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (ringingCall.getState() == CdmaCall.State.INCOMING) {
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.i("phone", "acceptCall: incoming...");
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Always unmute when answering a new call
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setMute(false);
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.acceptCall(obtainCompleteMessage());
2778a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause        } else if (ringingCall.getState() == CdmaCall.State.WAITING) {
27822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            CdmaConnection cwConn = (CdmaConnection)(ringingCall.getLatestConnection());
27922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
28022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // Since there is no network response for supplimentary
28122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // service for CDMA, we assume call waiting is answered.
28222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // ringing Call state change to idle is in CdmaCall.detach
28322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // triggered by updateParent.
28422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            cwConn.updateParent(ringingCall, foregroundCall);
28522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            cwConn.onConnectedInOrOut();
28684d5585b99f08caba384c933906c0da175fce995Cheng Yang            updatePhoneState();
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switchWaitingOrHoldingAndActive();
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException("phone not ringing");
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
294767a662ecde33c3979bf02b793d392aca0403162Wink Saville    rejectCall () throws CallStateException {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // AT+CHLD=0 means "release held or UDUB"
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // so if the phone isn't ringing, this could hang up held
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ringingCall.getState().isRinging()) {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.rejectCall(obtainCompleteMessage());
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException("phone not ringing");
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switchWaitingOrHoldingAndActive() throws CallStateException {
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Should we bother with this check?
307767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (ringingCall.getState() == CdmaCall.State.INCOMING) {
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException("cannot be in the incoming state");
3095abc78405f03e739f972692aa100f25609301ff5Guo-Bin Zhang        } else if (foregroundCall.getConnections().size() > 1) {
31022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            flashAndSetGenericTrue();
3115abc78405f03e739f972692aa100f25609301ff5Guo-Bin Zhang        } else {
3125abc78405f03e739f972692aa100f25609301ff5Guo-Bin Zhang            // Send a flash command to CDMA network for putting the other party on hold.
3135abc78405f03e739f972692aa100f25609301ff5Guo-Bin Zhang            // For CDMA networks which do not support this the user would just hear a beep
3145abc78405f03e739f972692aa100f25609301ff5Guo-Bin Zhang            // from the network. For CDMA networks which do support it will put the other
3155abc78405f03e739f972692aa100f25609301ff5Guo-Bin Zhang            // party on hold.
3165abc78405f03e739f972692aa100f25609301ff5Guo-Bin Zhang            cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
321767a662ecde33c3979bf02b793d392aca0403162Wink Saville    conference() throws CallStateException {
32222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Should we be checking state?
32322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        flashAndSetGenericTrue();
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
327767a662ecde33c3979bf02b793d392aca0403162Wink Saville    explicitCallTransfer() throws CallStateException {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void
332767a662ecde33c3979bf02b793d392aca0403162Wink Saville    clearDisconnected() {
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        internalClearDisconnected();
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updatePhoneState();
3361c42769339d8fe98ecb2698c64e7dc6672e3d59dJaikumar Ganesh        phone.notifyPreciseCallStateChanged();
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean
340767a662ecde33c3979bf02b793d392aca0403162Wink Saville    canConference() {
341767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return foregroundCall.getState() == CdmaCall.State.ACTIVE
342767a662ecde33c3979bf02b793d392aca0403162Wink Saville                && backgroundCall.getState() == CdmaCall.State.HOLDING
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && !backgroundCall.isFull()
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && !foregroundCall.isFull();
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean
348767a662ecde33c3979bf02b793d392aca0403162Wink Saville    canDial() {
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean ret;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int serviceState = phone.getServiceState().getState();
351597f2b7022db1368831251d776f42b98d10ba2cdjohnwang        String disableCall = SystemProperties.get(
352597f2b7022db1368831251d776f42b98d10ba2cdjohnwang                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
354597f2b7022db1368831251d776f42b98d10ba2cdjohnwang        ret = (serviceState != ServiceState.STATE_POWER_OFF)
355597f2b7022db1368831251d776f42b98d10ba2cdjohnwang                && pendingMO == null
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && !ringingCall.isRinging()
357597f2b7022db1368831251d776f42b98d10ba2cdjohnwang                && !disableCall.equals("true")
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && (!foregroundCall.getState().isAlive()
359597f2b7022db1368831251d776f42b98d10ba2cdjohnwang                    || (foregroundCall.getState() == CdmaCall.State.ACTIVE)
360597f2b7022db1368831251d776f42b98d10ba2cdjohnwang                    || !backgroundCall.getState().isAlive());
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
362fd2d01302781af91d77557a99874111a4fee8365Wink Saville        if (!ret) {
363fd2d01302781af91d77557a99874111a4fee8365Wink Saville            log(String.format("canDial is false\n" +
364fd2d01302781af91d77557a99874111a4fee8365Wink Saville                              "((serviceState=%d) != ServiceState.STATE_POWER_OFF)::=%s\n" +
365fd2d01302781af91d77557a99874111a4fee8365Wink Saville                              "&& pendingMO == null::=%s\n" +
366fd2d01302781af91d77557a99874111a4fee8365Wink Saville                              "&& !ringingCall.isRinging()::=%s\n" +
367fd2d01302781af91d77557a99874111a4fee8365Wink Saville                              "&& !disableCall.equals(\"true\")::=%s\n" +
368fd2d01302781af91d77557a99874111a4fee8365Wink Saville                              "&& (!foregroundCall.getState().isAlive()::=%s\n" +
369fd2d01302781af91d77557a99874111a4fee8365Wink Saville                              "   || foregroundCall.getState() == CdmaCall.State.ACTIVE::=%s\n" +
370fd2d01302781af91d77557a99874111a4fee8365Wink Saville                              "   ||!backgroundCall.getState().isAlive())::=%s)",
371fd2d01302781af91d77557a99874111a4fee8365Wink Saville                    serviceState,
372fd2d01302781af91d77557a99874111a4fee8365Wink Saville                    serviceState != ServiceState.STATE_POWER_OFF,
373fd2d01302781af91d77557a99874111a4fee8365Wink Saville                    pendingMO == null,
374fd2d01302781af91d77557a99874111a4fee8365Wink Saville                    !ringingCall.isRinging(),
375fd2d01302781af91d77557a99874111a4fee8365Wink Saville                    !disableCall.equals("true"),
376fd2d01302781af91d77557a99874111a4fee8365Wink Saville                    !foregroundCall.getState().isAlive(),
377fd2d01302781af91d77557a99874111a4fee8365Wink Saville                    foregroundCall.getState() == CdmaCall.State.ACTIVE,
378fd2d01302781af91d77557a99874111a4fee8365Wink Saville                    !backgroundCall.getState().isAlive()));
379fd2d01302781af91d77557a99874111a4fee8365Wink Saville        }
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ret;
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean
384767a662ecde33c3979bf02b793d392aca0403162Wink Saville    canTransfer() {
385767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
386767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return false;
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //***** Private Instance Methods
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
392767a662ecde33c3979bf02b793d392aca0403162Wink Saville    internalClearDisconnected() {
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ringingCall.clearDisconnected();
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        foregroundCall.clearDisconnected();
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        backgroundCall.clearDisconnected();
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Obtain a message to use for signalling "invoke getCurrentCalls() when
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this operation and all other pending operations are complete
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Message
403767a662ecde33c3979bf02b793d392aca0403162Wink Saville    obtainCompleteMessage() {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Obtain a message to use for signalling "invoke getCurrentCalls() when
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this operation and all other pending operations are complete
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Message
412767a662ecde33c3979bf02b793d392aca0403162Wink Saville    obtainCompleteMessage(int what) {
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pendingOperations++;
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lastRelevantPoll = null;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        needsPoll = true;
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pendingOperations + ", needsPoll=" + needsPoll);
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return obtainMessage(what);
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
424767a662ecde33c3979bf02b793d392aca0403162Wink Saville    operationComplete() {
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pendingOperations--;
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG_POLL) log("operationComplete: pendingOperations=" +
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pendingOperations + ", needsPoll=" + needsPoll);
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pendingOperations == 0 && needsPoll) {
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.getCurrentCalls(lastRelevantPoll);
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (pendingOperations < 0) {
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // this should never happen
435767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.e(LOG_TAG,"CdmaCallTracker.pendingOperations < 0");
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pendingOperations = 0;
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void
443767a662ecde33c3979bf02b793d392aca0403162Wink Saville    updatePhoneState() {
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Phone.State oldState = state;
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ringingCall.isRinging()) {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = Phone.State.RINGING;
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (pendingMO != null ||
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                !(foregroundCall.isIdle() && backgroundCall.isIdle())) {
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = Phone.State.OFFHOOK;
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            state = Phone.State.IDLE;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (state == Phone.State.IDLE && oldState != state) {
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            voiceCallEndedRegistrants.notifyRegistrants(
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                new AsyncResult(null, null, null));
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (oldState == Phone.State.IDLE && oldState != state) {
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            voiceCallStartedRegistrants.notifyRegistrants (
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    new AsyncResult(null, null, null));
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4622189daf50c174b5bed048a2777fae8b57df8e467Libin Tang        if (Phone.DEBUG_PHONE) {
463b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville            log("update phone state, old=" + oldState + " new="+ state);
4642189daf50c174b5bed048a2777fae8b57df8e467Libin Tang        }
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (state != oldState) {
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.notifyPhoneStateChanged();
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
470767a662ecde33c3979bf02b793d392aca0403162Wink Saville    // ***** Overwritten from CallTracker
471767a662ecde33c3979bf02b793d392aca0403162Wink Saville
472767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void
473767a662ecde33c3979bf02b793d392aca0403162Wink Saville    handlePollCalls(AsyncResult ar) {
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        List polledCalls;
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ar.exception == null) {
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            polledCalls = (List)ar.result;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // just a dummy empty ArrayList to cause the loop
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to hang up all the calls
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            polledCalls = new ArrayList();
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Radio probably wasn't ready--try again in a bit
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // But don't keep polling if the channel is closed
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pollCallsAfterDelay();
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Connection newRinging = null; //or waiting
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasNonHangupStateChanged = false;   // Any change besides
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    // a dropped connection
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean needsPollDelay = false;
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean unknownConnectionAppeared = false;
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0, curDC = 0, dcSize = polledCalls.size()
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ; i < connections.length; i++) {
497767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CdmaConnection conn = connections[i];
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            DriverCall dc = null;
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // polledCall list is sparse
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (curDC < dcSize) {
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dc = (DriverCall) polledCalls.get(curDC);
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (dc.index == i+1) {
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curDC++;
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    dc = null;
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    conn+", dc=" + dc);
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (conn == null && dc != null) {
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Connection appeared in CLCC response that we don't know about
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (pendingMO != null && pendingMO.compareTo(dc)) {
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (DBG_POLL) log("poll: pendingMO=" + pendingMO);
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // It's our pending mobile originating call
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    connections[i] = pendingMO;
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    pendingMO.index = i;
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    pendingMO.update(dc);
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    pendingMO = null;
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Someone has already asked to hangup this call
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (hangupPendingMO) {
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hangupPendingMO = false;
52995a1d1a89e383dab893750638c2393dec54833ffWink Saville                        // Re-start Ecm timer when an uncompleted emergency call ends
53095a1d1a89e383dab893750638c2393dec54833ffWink Saville                        if (mIsEcmTimerCanceled) {
53195a1d1a89e383dab893750638c2393dec54833ffWink Saville                            handleEcmTimer(phone.RESTART_ECM_TIMER);
53295a1d1a89e383dab893750638c2393dec54833ffWink Saville                        }
53395a1d1a89e383dab893750638c2393dec54833ffWink Saville
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (Phone.DEBUG_PHONE) log(
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "poll: hangupPendingMO, hangup conn " + i);
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hangup(connections[i]);
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (CallStateException ex) {
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            Log.e(LOG_TAG, "unexpected error on hangup");
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Do not continue processing this poll
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Wait for hangup and repoll
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return;
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
5472189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    if (Phone.DEBUG_PHONE) {
548b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                        log("pendingMo=" + pendingMO + ", dc=" + dc);
5492189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    }
5502189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    // find if the MT call is a new ring or unknown connection
5512189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    newRinging = checkMtFindNewRinging(dc,i);
5522189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    if (newRinging == null) {
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        unknownConnectionAppeared = true;
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
555b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                    checkAndEnableDataCallAfterEmergencyCallDropped();
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasNonHangupStateChanged = true;
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (conn != null && dc == null) {
559b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                // This case means the RIL has no more active call anymore and
560b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                // we need to clean up the foregroundCall and ringingCall.
561b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                // Loop through foreground call connections as
562b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                // it contains the known logical connections.
56322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                int count = foregroundCall.connections.size();
564b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                for (int n = 0; n < count; n++) {
565b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                    if (Phone.DEBUG_PHONE) log("adding fgCall cn " + n + " to droppedDuringPoll");
566b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                    CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n);
567b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                    droppedDuringPoll.add(cn);
568b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                }
569b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                count = ringingCall.connections.size();
570b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                // Loop through ringing call connections as
571b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                // it may contain the known logical connections.
572b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                for (int n = 0; n < count; n++) {
573b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                    if (Phone.DEBUG_PHONE) log("adding rgCall cn " + n + " to droppedDuringPoll");
574b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                    CdmaConnection cn = (CdmaConnection)ringingCall.connections.get(n);
575b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                    droppedDuringPoll.add(cn);
57622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                }
57722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                foregroundCall.setGeneric(false);
578b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                ringingCall.setGeneric(false);
57995a1d1a89e383dab893750638c2393dec54833ffWink Saville
58095a1d1a89e383dab893750638c2393dec54833ffWink Saville                // Re-start Ecm timer when the connected emergency call ends
58195a1d1a89e383dab893750638c2393dec54833ffWink Saville                if (mIsEcmTimerCanceled) {
58295a1d1a89e383dab893750638c2393dec54833ffWink Saville                    handleEcmTimer(phone.RESTART_ECM_TIMER);
58395a1d1a89e383dab893750638c2393dec54833ffWink Saville                }
584b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                // If emergency call is not going through while dialing
585b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                checkAndEnableDataCallAfterEmergencyCallDropped();
58695a1d1a89e383dab893750638c2393dec54833ffWink Saville
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Dropped connections are removed from the CallTracker
588767a662ecde33c3979bf02b793d392aca0403162Wink Saville                // list but kept in the Call list
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                connections[i] = null;
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
5912189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                // Call collision case
5922189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                if (conn.isIncoming != dc.isMT) {
5932189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    if (dc.isMT == true){
5942189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        // Mt call takes precedence than Mo,drops Mo
5952189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        droppedDuringPoll.add(conn);
5962189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        // find if the MT call is a new ring or unknown connection
5972189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        newRinging = checkMtFindNewRinging(dc,i);
5982189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        if (newRinging == null) {
5992189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                            unknownConnectionAppeared = true;
6002189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        }
601b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                        checkAndEnableDataCallAfterEmergencyCallDropped();
6022189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    } else {
6032189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        // Call info stored in conn is not consistent with the call info from dc.
6042189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        // We should follow the rule of MT calls taking precedence over MO calls
6052189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        // when there is conflict, so here we drop the call info from dc and
6062189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        // continue to use the call info from conn, and only take a log.
6072189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                        Log.e(LOG_TAG,"Error in RIL, Phantom call appeared " + dc);
6082189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    }
6092189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                } else {
6102189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    boolean changed;
6112189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    changed = conn.update(dc);
6122189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                    hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
6132189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                }
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (REPEAT_POLLING) {
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (dc != null) {
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // FIXME with RIL, we should not need this anymore
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((dc.state == DriverCall.State.DIALING
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || (dc.state == DriverCall.State.ALERTING
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || (dc.state == DriverCall.State.INCOMING
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || (dc.state == DriverCall.State.WAITING
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ) {
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Sometimes there's no unsolicited notification
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // for state transitions
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        needsPollDelay = true;
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // This is the first poll after an ATD.
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We expect the pending call to appear in the list
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If it does not, we land here
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pendingMO != null) {
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + foregroundCall.getState());
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            droppedDuringPoll.add(pendingMO);
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pendingMO = null;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hangupPendingMO = false;
64695a1d1a89e383dab893750638c2393dec54833ffWink Saville            if( pendingCallInEcm) {
64795a1d1a89e383dab893750638c2393dec54833ffWink Saville                pendingCallInEcm = false;
648dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newRinging != null) {
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.notifyNewRingingConnection(newRinging);
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // clear the "local hangup" and "missed/rejected call"
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // cases from the "dropped during poll" list
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // These cases need no "last call fail" reason
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) {
659767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CdmaConnection conn = droppedDuringPoll.get(i);
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (conn.isIncoming() && conn.getConnectTime() == 0) {
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Missed or rejected call
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Connection.DisconnectCause cause;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (conn.cause == Connection.DisconnectCause.LOCAL) {
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    cause = Connection.DisconnectCause.INCOMING_REJECTED;
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    cause = Connection.DisconnectCause.INCOMING_MISSED;
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Phone.DEBUG_PHONE) {
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    log("missed/rejected call, conn.cause=" + conn.cause);
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    log("setting cause to " + cause);
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                droppedDuringPoll.remove(i);
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                conn.onDisconnect(cause);
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (conn.cause == Connection.DisconnectCause.LOCAL) {
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Local hangup
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                droppedDuringPoll.remove(i);
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                conn.onDisconnect(Connection.DisconnectCause.LOCAL);
680767a662ecde33c3979bf02b793d392aca0403162Wink Saville            } else if (conn.cause == Connection.DisconnectCause.INVALID_NUMBER) {
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                droppedDuringPoll.remove(i);
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER);
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Any non-local disconnects: determine cause
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (droppedDuringPoll.size() > 0) {
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.getLastCallFailCause(
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (needsPollDelay) {
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pollCallsAfterDelay();
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Cases when we can no longer keep disconnected Connection's
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // with their previous calls
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // 1) the phone has started to ring
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // 2) A Call/Connection object has changed state...
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //    we may have switched or held or answered (but not hung up)
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newRinging != null || hasNonHangupStateChanged) {
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            internalClearDisconnected();
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updatePhoneState();
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (unknownConnectionAppeared) {
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.notifyUnknownConnection();
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasNonHangupStateChanged || newRinging != null) {
7121c42769339d8fe98ecb2698c64e7dc6672e3d59dJaikumar Ganesh            phone.notifyPreciseCallStateChanged();
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //dumpState();
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
718767a662ecde33c3979bf02b793d392aca0403162Wink Saville    //***** Called from CdmaConnection
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ void
720767a662ecde33c3979bf02b793d392aca0403162Wink Saville    hangup (CdmaConnection conn) throws CallStateException {
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (conn.owner != this) {
722767a662ecde33c3979bf02b793d392aca0403162Wink Saville            throw new CallStateException ("CdmaConnection " + conn
723767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                    + "does not belong to CdmaCallTracker " + this);
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (conn == pendingMO) {
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We're hanging up an outgoing call that doesn't have it's
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // GSM index assigned yet
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hangupPendingMO = true;
73222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        } else if ((conn.getCall() == ringingCall)
73322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                && (ringingCall.getState() == CdmaCall.State.WAITING)) {
73422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // Handle call waiting hang up case.
73522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            //
73622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // The ringingCall state will change to IDLE in CdmaCall.detach
73722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // if the ringing call connection size is 0. We don't specifically
73822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // set the ringing call state to IDLE here to avoid a race condition
73922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // where a new call waiting could get a hang up from an old call
74022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            // waiting ringingCall.
7418a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause            //
7428a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause            // PhoneApp does the call log itself since only PhoneApp knows
7438a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause            // the hangup reason is user ignoring or timing out. So conn.onDisconnect()
7448a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause            // is not called here. Instead, conn.onLocalDisconnect() is called.
7458a9ae45015a4cabdd56b1160261d4e7cbe551014David Krause            conn.onLocalDisconnect();
74684d5585b99f08caba384c933906c0da175fce995Cheng Yang            updatePhoneState();
7478125864adcf27f706f261903ae5adf84f30b1987Ling Li            phone.notifyPreciseCallStateChanged();
74822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            return;
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
751767a662ecde33c3979bf02b793d392aca0403162Wink Saville                cm.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage());
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (CallStateException ex) {
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Ignore "connection not found"
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Call may have hung up already
755767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.w(LOG_TAG,"CdmaCallTracker WARN: hangup() on absent connection "
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                + conn);
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        conn.onHangupLocal();
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ void
764767a662ecde33c3979bf02b793d392aca0403162Wink Saville    separate (CdmaConnection conn) throws CallStateException {
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (conn.owner != this) {
766767a662ecde33c3979bf02b793d392aca0403162Wink Saville            throw new CallStateException ("CdmaConnection " + conn
767767a662ecde33c3979bf02b793d392aca0403162Wink Saville                                    + "does not belong to CdmaCallTracker " + this);
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
770767a662ecde33c3979bf02b793d392aca0403162Wink Saville            cm.separateConnection (conn.getCDMAIndex(),
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                obtainCompleteMessage(EVENT_SEPARATE_RESULT));
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (CallStateException ex) {
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Ignore "connection not found"
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Call may have hung up already
775767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.w(LOG_TAG,"CdmaCallTracker WARN: separate() on absent connection "
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          + conn);
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
780767a662ecde33c3979bf02b793d392aca0403162Wink Saville    //***** Called from CDMAPhone
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ void
783767a662ecde33c3979bf02b793d392aca0403162Wink Saville    setMute(boolean mute) {
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        desiredMute = mute;
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.setMute(desiredMute, null);
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ boolean
789767a662ecde33c3979bf02b793d392aca0403162Wink Saville    getMute() {
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return desiredMute;
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
794767a662ecde33c3979bf02b793d392aca0403162Wink Saville    //***** Called from CdmaCall
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */ void
797767a662ecde33c3979bf02b793d392aca0403162Wink Saville    hangup (CdmaCall call) throws CallStateException {
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (call.getConnections().size() == 0) {
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CallStateException("no connections in call");
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (call == ringingCall) {
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.hangupWaitingOrBackground(obtainCompleteMessage());
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (call == foregroundCall) {
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (call.isDialingOrAlerting()) {
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Phone.DEBUG_PHONE) {
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    log("(foregnd) hangup dialing or alerting...");
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
810767a662ecde33c3979bf02b793d392aca0403162Wink Saville                hangup((CdmaConnection)(call.getConnections().get(0)));
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hangupForegroundResumeBackground();
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (call == backgroundCall) {
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ringingCall.isRinging()) {
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Phone.DEBUG_PHONE) {
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    log("hangup all conns in background call");
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hangupAllConnections(call);
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hangupWaitingOrBackground();
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
824767a662ecde33c3979bf02b793d392aca0403162Wink Saville            throw new RuntimeException ("CdmaCall " + call +
825767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    "does not belong to CdmaCallTracker " + this);
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        call.onHangupLocal();
829e7a9201edbb4d18f12d00ba1b80e2481a5cb446fjsh        phone.notifyPreciseCallStateChanged();
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void hangupWaitingOrBackground() {
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.hangupWaitingOrBackground(obtainCompleteMessage());
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void hangupForegroundResumeBackground() {
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.hangupForegroundResumeBackground(obtainCompleteMessage());
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
844767a662ecde33c3979bf02b793d392aca0403162Wink Saville    void hangupConnectionByIndex(CdmaCall call, int index)
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws CallStateException {
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = call.connections.size();
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
848767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CdmaConnection cn = (CdmaConnection)call.connections.get(i);
849767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (cn.getCDMAIndex() == index) {
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm.hangupConnection(index, obtainCompleteMessage());
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw new CallStateException("no gsm index found");
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
858767a662ecde33c3979bf02b793d392aca0403162Wink Saville    void hangupAllConnections(CdmaCall call) throws CallStateException{
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int count = call.connections.size();
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
862767a662ecde33c3979bf02b793d392aca0403162Wink Saville                CdmaConnection cn = (CdmaConnection)call.connections.get(i);
863767a662ecde33c3979bf02b793d392aca0403162Wink Saville                cm.hangupConnection(cn.getCDMAIndex(), obtainCompleteMessage());
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (CallStateException ex) {
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */
871767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaConnection getConnectionByIndex(CdmaCall call, int index)
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws CallStateException {
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = call.connections.size();
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
875767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CdmaConnection cn = (CdmaConnection)call.connections.get(i);
876767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (cn.getCDMAIndex() == index) {
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return cn;
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
88422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    private void flashAndSetGenericTrue() throws CallStateException {
88522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
88622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
88722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Set generic to true because in CDMA it is not known what
88822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // the status of the call is after a call waiting is answered,
88922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // 3 way call merged or a switch between calls.
89022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        foregroundCall.setGeneric(true);
8911c42769339d8fe98ecb2698c64e7dc6672e3d59dJaikumar Ganesh        phone.notifyPreciseCallStateChanged();
89222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
89322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Phone.SuppService getFailedService(int what) {
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (what) {
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SWITCH_RESULT:
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return Phone.SuppService.SWITCH;
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_CONFERENCE_RESULT:
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return Phone.SuppService.CONFERENCE;
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SEPARATE_RESULT:
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return Phone.SuppService.SEPARATE;
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_ECT_RESULT:
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return Phone.SuppService.TRANSFER;
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Phone.SuppService.UNKNOWN;
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
908767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private void handleRadioNotAvailable() {
909767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // handlePollCalls will clear out its
910767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // call list when it gets the CommandException
911767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // error result from this
912767a662ecde33c3979bf02b793d392aca0403162Wink Saville        pollCallsWhenSafe();
913767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
914767a662ecde33c3979bf02b793d392aca0403162Wink Saville
91522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) {
91622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        if (callWaitingRegistrants != null) {
91722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            callWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null));
91822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        }
91922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
92022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
92122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    private void handleCallWaitingInfo (CdmaCallWaitingNotification cw) {
92222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Check how many connections in foregroundCall.
92322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // If the connection in foregroundCall is more
92422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // than one, then the connection information is
92522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // not reliable anymore since it means either
92622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // call waiting is connected or 3 way call is
92722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // dialed before, so set generic.
92822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        if (foregroundCall.connections.size() > 1 ) {
92922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            foregroundCall.setGeneric(true);
93022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        }
93122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
93222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Create a new CdmaConnection which attaches itself to ringingCall.
93322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        ringingCall.setGeneric(false);
93422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        new CdmaConnection(phone.getContext(), cw, this, ringingCall);
93584d5585b99f08caba384c933906c0da175fce995Cheng Yang        updatePhoneState();
93622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
93722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        // Finally notify application
93822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville        notifyCallWaitingInfo(cw);
93922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    }
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //****** Overridden from Handler
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void
943767a662ecde33c3979bf02b793d392aca0403162Wink Saville    handleMessage (Message msg) {
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AsyncResult ar;
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (msg.what) {
947767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case EVENT_POLL_CALLS_RESULT:{
948767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult)msg.obj;
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
951767a662ecde33c3979bf02b793d392aca0403162Wink Saville                if(msg == lastRelevantPoll) {
952767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    if(DBG_POLL) log(
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    needsPoll = false;
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    lastRelevantPoll = null;
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handlePollCalls((AsyncResult)msg.obj);
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
958767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_OPERATION_COMPLETE:
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                operationComplete();
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SWITCH_RESULT:
96622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                 // In GSM call operationComplete() here which gets the
96722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                 // current call list. But in CDMA there is no list so
96822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                 // there is nothing to do.
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_GET_LAST_CALL_FAIL_CAUSE:
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int causeCode;
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult)msg.obj;
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                operationComplete();
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (ar.exception != null) {
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // An exception occurred...just treat the disconnect
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // cause as "normal"
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    causeCode = CallFailCause.NORMAL_CLEARING;
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.i(LOG_TAG,
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "Exception during getLastCallFailCause, assuming normal disconnect");
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    causeCode = ((int[])ar.result)[0];
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i = 0, s =  droppedDuringPoll.size()
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ; i < s ; i++
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ) {
990767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    CdmaConnection conn = droppedDuringPoll.get(i);
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    conn.onRemoteDisconnect(causeCode);
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                updatePhoneState();
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9971c42769339d8fe98ecb2698c64e7dc6672e3d59dJaikumar Ganesh                phone.notifyPreciseCallStateChanged();
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                droppedDuringPoll.clear();
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10014be0d4378c3d9c79a094e99ce429907f1e9eda5fWink Saville            case EVENT_REPOLL_AFTER_DELAY:
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_CALL_STATE_CHANGE:
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollCallsWhenSafe();
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_RADIO_AVAILABLE:
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                handleRadioAvailable();
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_RADIO_NOT_AVAILABLE:
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                handleRadioNotAvailable();
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
1013767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1014dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            case EVENT_EXIT_ECM_RESPONSE_CDMA:
1015dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville               //no matter the result, we still do the same here
101695a1d1a89e383dab893750638c2393dec54833ffWink Saville               if (pendingCallInEcm) {
1017dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                   cm.dial(pendingMO.address, pendingCallClirMode, obtainCompleteMessage());
101895a1d1a89e383dab893750638c2393dec54833ffWink Saville                   pendingCallInEcm = false;
1019dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville               }
1020dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville               phone.unsetOnEcbModeExitResponse(this);
1021dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            break;
1022dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
102322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            case EVENT_CALL_WAITING_INFO_CDMA:
102422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville               ar = (AsyncResult)msg.obj;
102522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville               if (ar.exception == null) {
102622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                   handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result);
102722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                   Log.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received");
102822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville               }
102922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            break;
103022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
103122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA:
103222ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                ar = (AsyncResult)msg.obj;
103322ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                if (ar.exception == null) {
103422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    // Assume 3 way call is connected
103522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    pendingMO.onConnectedInOrOut();
1036e30d4bf531cf8873f345cff0503974952c2daf65Jinghui Guo                    pendingMO = null;
103722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                }
103822ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville            break;
103922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville
1040767a662ecde33c3979bf02b793d392aca0403162Wink Saville            default:{
1041dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville               throw new RuntimeException("unexpected event not handled");
1042767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
104695a1d1a89e383dab893750638c2393dec54833ffWink Saville    /**
104795a1d1a89e383dab893750638c2393dec54833ffWink Saville     * Handle Ecm timer to be canceled or re-started
104895a1d1a89e383dab893750638c2393dec54833ffWink Saville     */
104995a1d1a89e383dab893750638c2393dec54833ffWink Saville    private void handleEcmTimer(int action) {
105095a1d1a89e383dab893750638c2393dec54833ffWink Saville        phone.handleTimerInEmergencyCallbackMode(action);
105195a1d1a89e383dab893750638c2393dec54833ffWink Saville        switch(action) {
105295a1d1a89e383dab893750638c2393dec54833ffWink Saville        case CDMAPhone.CANCEL_ECM_TIMER: mIsEcmTimerCanceled = true; break;
105395a1d1a89e383dab893750638c2393dec54833ffWink Saville        case CDMAPhone.RESTART_ECM_TIMER: mIsEcmTimerCanceled = false; break;
105495a1d1a89e383dab893750638c2393dec54833ffWink Saville        default:
105595a1d1a89e383dab893750638c2393dec54833ffWink Saville            Log.e(LOG_TAG, "handleEcmTimer, unsupported action " + action);
105695a1d1a89e383dab893750638c2393dec54833ffWink Saville        }
105795a1d1a89e383dab893750638c2393dec54833ffWink Saville    }
105895a1d1a89e383dab893750638c2393dec54833ffWink Saville
10591cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang    /**
10601cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang     * Disable data call when emergency call is connected
10611cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang     */
10621cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang    private void disableDataCallInEmergencyCall(String dialString) {
10636b7c3f8a1cd8b638defc28a3249746e99b8039aeShaopeng Jia        if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) {
1064b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville            if (Phone.DEBUG_PHONE) log("disableDataCallInEmergencyCall");
10651cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang            mIsInEmergencyCall = true;
106663edf6c4f5795009e55f2ae9556550c38daa9774Robert Greenwalt            phone.mDataConnectionTracker.setInternalDataEnabled(false);
10671cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang        }
10681cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang    }
1069b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville
1070b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville    /**
1071b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville     * Check and enable data call after an emergency call is dropped if it's
1072b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville     * not in ECM
1073b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville     */
1074b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville    private void checkAndEnableDataCallAfterEmergencyCallDropped() {
1075b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville        if (mIsInEmergencyCall) {
1076984d22b180e68d6b9f8e2c81c4eb271deccfc94aRobert Greenwalt            mIsInEmergencyCall = false;
1077b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville            String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
1078b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville            if (Phone.DEBUG_PHONE) {
1079b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                log("checkAndEnableDataCallAfterEmergencyCallDropped,inEcm=" + inEcm);
1080b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville            }
1081b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville            if (inEcm.compareTo("false") == 0) {
1082b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville                // Re-initiate data connection
108363edf6c4f5795009e55f2ae9556550c38daa9774Robert Greenwalt                phone.mDataConnectionTracker.setInternalDataEnabled(true);
1084b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville            }
1085b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville        }
1086b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville    }
1087b14300140d9f8b0af4d573eb0420035f814e2d03Wink Saville
10882189daf50c174b5bed048a2777fae8b57df8e467Libin Tang    /**
10892189daf50c174b5bed048a2777fae8b57df8e467Libin Tang     * Check the MT call to see if it's a new ring or
10902189daf50c174b5bed048a2777fae8b57df8e467Libin Tang     * a unknown connection.
10912189daf50c174b5bed048a2777fae8b57df8e467Libin Tang     */
10922189daf50c174b5bed048a2777fae8b57df8e467Libin Tang    private Connection checkMtFindNewRinging(DriverCall dc, int i) {
10932189daf50c174b5bed048a2777fae8b57df8e467Libin Tang
10942189daf50c174b5bed048a2777fae8b57df8e467Libin Tang        Connection newRinging = null;
10952189daf50c174b5bed048a2777fae8b57df8e467Libin Tang
10962189daf50c174b5bed048a2777fae8b57df8e467Libin Tang        connections[i] = new CdmaConnection(phone.getContext(), dc, this, i);
10972189daf50c174b5bed048a2777fae8b57df8e467Libin Tang        // it's a ringing call
10982189daf50c174b5bed048a2777fae8b57df8e467Libin Tang        if (connections[i].getCall() == ringingCall) {
10992189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            newRinging = connections[i];
11002189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            if (Phone.DEBUG_PHONE) log("Notify new ring " + dc);
11012189daf50c174b5bed048a2777fae8b57df8e467Libin Tang        } else {
11022189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            // Something strange happened: a call which is neither
11032189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            // a ringing call nor the one we created. It could be the
11042189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            // call collision result from RIL
11052189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            Log.e(LOG_TAG,"Phantom call appeared " + dc);
11062189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            // If it's a connected call, set the connect time so that
11072189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            // it's non-zero.  It may not be accurate, but at least
11082189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            // it won't appear as a Missed Call.
11092189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            if (dc.state != DriverCall.State.ALERTING
11102189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                && dc.state != DriverCall.State.DIALING) {
11112189daf50c174b5bed048a2777fae8b57df8e467Libin Tang                connections[i].connectTime = System.currentTimeMillis();
11122189daf50c174b5bed048a2777fae8b57df8e467Libin Tang            }
11132189daf50c174b5bed048a2777fae8b57df8e467Libin Tang        }
11142189daf50c174b5bed048a2777fae8b57df8e467Libin Tang        return newRinging;
11152189daf50c174b5bed048a2777fae8b57df8e467Libin Tang    }
11161cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang
11171cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang    /**
11181cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang     * Check if current call is in emergency call
11191cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang     *
11201cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang     * @return true if it is in emergency call
11211cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang     *         false if it is not in emergency call
11221cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang     */
11231cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang    boolean isInEmergencyCall() {
11241cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang        return mIsInEmergencyCall;
11251cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang    }
11261cef22890d10417977397a5dccf34956858d0803Guo-Bin Zhang
1127767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void log(String msg) {
1128767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Log.d(LOG_TAG, "[CdmaCallTracker] " + msg);
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1130767a662ecde33c3979bf02b793d392aca0403162Wink Saville
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1132