10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License. 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License. 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.gsm; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant; 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties; 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.PhoneNumberUtils; 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.TelephonyManager; 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.gsm.GsmCellLocation; 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.EventLog; 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log; 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CallStateException; 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CallTracker; 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface; 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Connection; 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DriverCall; 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.EventLogTags; 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Phone; 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.PhoneConstants; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.TelephonyProperties; 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.UUSInfo; 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.CallFailCause; 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.GSMPhone; 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.GsmCall; 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.GsmConnection; 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor; 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List; 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList; 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide} 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic final class GsmCallTracker extends CallTracker { 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final String LOG_TAG = "GSM"; 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final boolean REPEAT_POLLING = false; 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final boolean DBG_POLL = false; 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Constants 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int MAX_CONNECTIONS = 7; // only 7 connections allowed in GSM 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int MAX_CONNECTIONS_PER_CALL = 5; // only 5 connections allowed per call 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Instance Variables 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmConnection connections[] = new GsmConnection[MAX_CONNECTIONS]; 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville RegistrantList voiceCallEndedRegistrants = new RegistrantList(); 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville RegistrantList voiceCallStartedRegistrants = new RegistrantList(); 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // connections dropped during last poll 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ArrayList<GsmConnection> droppedDuringPoll 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville = new ArrayList<GsmConnection>(MAX_CONNECTIONS); 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmCall ringingCall = new GsmCall(this); 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // A call that is ringing or (call) waiting 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmCall foregroundCall = new GsmCall(this); 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmCall backgroundCall = new GsmCall(this); 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmConnection pendingMO; 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean hangupPendingMO; 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GSMPhone phone; 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean desiredMute = false; // false = mute off 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville PhoneConstants.State state = PhoneConstants.State.IDLE; 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Events 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Constructors 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmCallTracker (GSMPhone phone) { 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this.phone = phone; 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm = phone.mCM; 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null); 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null); 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null); 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void dispose() { 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //Unregister for all events 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.unregisterForCallStateChanged(this); 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.unregisterForOn(this); 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.unregisterForNotAvailable(this); 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for(GsmConnection c : connections) { 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if(c != null) hangup(c); 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (CallStateException ex) { 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "unexpected error on hangup during dispose"); 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if(pendingMO != null) hangup(pendingMO); 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (CallStateException ex) { 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "unexpected error on hangup during dispose"); 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville clearDisconnected(); 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void finalize() { 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.d(LOG_TAG, "GsmCallTracker finalized"); 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Instance Methods 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Public Methods 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void registerForVoiceCallStarted(Handler h, int what, Object obj) { 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Registrant r = new Registrant(h, what, obj); 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville voiceCallStartedRegistrants.add(r); 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void unregisterForVoiceCallStarted(Handler h) { 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville voiceCallStartedRegistrants.remove(h); 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void registerForVoiceCallEnded(Handler h, int what, Object obj) { 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Registrant r = new Registrant(h, what, obj); 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville voiceCallEndedRegistrants.add(r); 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void unregisterForVoiceCallEnded(Handler h) { 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville voiceCallEndedRegistrants.remove(h); 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville fakeHoldForegroundBeforeDial() { 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville List<Connection> connCopy; 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // We need to make a copy here, since fakeHoldBeforeDial() 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // modifies the lists, and we don't want to reverse the order 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville connCopy = (List<Connection>) foregroundCall.connections.clone(); 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0, s = connCopy.size() ; i < s ; i++) { 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmConnection conn = (GsmConnection)connCopy.get(i); 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville conn.fakeHoldBeforeDial(); 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * clirMode is one of the CLIR_ constants 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized Connection 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException { 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // note that this triggers call state changed notif 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville clearDisconnected(); 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!canDial()) { 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new CallStateException("cannot dial in current state"); 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // The new call must be assigned to the foreground call. 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // That call must be idle, so place anything that's 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // there on hold 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (foregroundCall.getState() == GsmCall.State.ACTIVE) { 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // this will probably be done by the radio anyway 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // but the dial might fail before this happens 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // and we need to make sure the foreground call is clear 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // for the newly dialed connection 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switchWaitingOrHoldingAndActive(); 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Fake local state so that 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // a) foregroundCall is empty for the newly dialed connection 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // b) hasNonHangupStateChanged remains false in the 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // next poll, so that we don't clear a failed dialing call 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville fakeHoldForegroundBeforeDial(); 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (foregroundCall.getState() != GsmCall.State.IDLE) { 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //we should have failed in !canDial() above before we get here 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new CallStateException("cannot dial in current state"); 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingMO = new GsmConnection(phone.getContext(), checkForTestEmergencyNumber(dialString), 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this, foregroundCall); 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangupPendingMO = false; 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pendingMO.address == null || pendingMO.address.length() == 0 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ) { 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Phone number is invalid 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER; 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // handlePollCalls() will notice this call not present 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // and will mark it as dropped. 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pollCallsWhenSafe(); 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Always unmute when initiating a new call 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville setMute(false); 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.dial(pendingMO.address, clirMode, uusInfo, obtainCompleteMessage()); 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville updatePhoneState(); 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville phone.notifyPreciseCallStateChanged(); 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return pendingMO; 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Connection 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dial(String dialString) throws CallStateException { 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return dial(dialString, CommandsInterface.CLIR_DEFAULT, null); 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Connection 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dial(String dialString, UUSInfo uusInfo) throws CallStateException { 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo); 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Connection 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dial(String dialString, int clirMode) throws CallStateException { 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return dial(dialString, clirMode, null); 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville acceptCall () throws CallStateException { 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // FIXME if SWITCH fails, should retry with ANSWER 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // in case the active/holding call disappeared and this 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // is no longer call waiting 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ringingCall.getState() == GsmCall.State.INCOMING) { 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.i("phone", "acceptCall: incoming..."); 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Always unmute when answering a new call 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville setMute(false); 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.acceptCall(obtainCompleteMessage()); 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (ringingCall.getState() == GsmCall.State.WAITING) { 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville setMute(false); 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switchWaitingOrHoldingAndActive(); 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new CallStateException("phone not ringing"); 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville rejectCall () throws CallStateException { 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // AT+CHLD=0 means "release held or UDUB" 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // so if the phone isn't ringing, this could hang up held 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ringingCall.getState().isRinging()) { 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.rejectCall(obtainCompleteMessage()); 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new CallStateException("phone not ringing"); 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switchWaitingOrHoldingAndActive() throws CallStateException { 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Should we bother with this check? 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ringingCall.getState() == GsmCall.State.INCOMING) { 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new CallStateException("cannot be in the incoming state"); 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.switchWaitingOrHoldingAndActive( 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville obtainCompleteMessage(EVENT_SWITCH_RESULT)); 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville conference() throws CallStateException { 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT)); 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville explicitCallTransfer() throws CallStateException { 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT)); 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville clearDisconnected() { 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville internalClearDisconnected(); 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville updatePhoneState(); 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville phone.notifyPreciseCallStateChanged(); 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville canConference() { 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return foregroundCall.getState() == GsmCall.State.ACTIVE 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && backgroundCall.getState() == GsmCall.State.HOLDING 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && !backgroundCall.isFull() 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && !foregroundCall.isFull(); 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville canDial() { 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean ret; 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int serviceState = phone.getServiceState().getState(); 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String disableCall = SystemProperties.get( 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville TelephonyProperties.PROPERTY_DISABLE_CALL, "false"); 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = (serviceState != ServiceState.STATE_POWER_OFF) 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && pendingMO == null 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && !ringingCall.isRinging() 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && !disableCall.equals("true") 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && (!foregroundCall.getState().isAlive() 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville || !backgroundCall.getState().isAlive()); 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret; 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville canTransfer() { 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return foregroundCall.getState() == GsmCall.State.ACTIVE 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && backgroundCall.getState() == GsmCall.State.HOLDING; 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Private Instance Methods 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville internalClearDisconnected() { 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ringingCall.clearDisconnected(); 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville foregroundCall.clearDisconnected(); 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville backgroundCall.clearDisconnected(); 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Obtain a message to use for signalling "invoke getCurrentCalls() when 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * this operation and all other pending operations are complete 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private Message 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville obtainCompleteMessage() { 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return obtainCompleteMessage(EVENT_OPERATION_COMPLETE); 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Obtain a message to use for signalling "invoke getCurrentCalls() when 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * this operation and all other pending operations are complete 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private Message 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville obtainCompleteMessage(int what) { 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingOperations++; 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville lastRelevantPoll = null; 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville needsPoll = true; 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" + 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingOperations + ", needsPoll=" + needsPoll); 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return obtainMessage(what); 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville operationComplete() { 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingOperations--; 3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG_POLL) log("operationComplete: pendingOperations=" + 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingOperations + ", needsPoll=" + needsPoll); 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pendingOperations == 0 && needsPoll) { 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); 3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.getCurrentCalls(lastRelevantPoll); 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (pendingOperations < 0) { 3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // this should never happen 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG,"GsmCallTracker.pendingOperations < 0"); 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingOperations = 0; 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville updatePhoneState() { 3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville PhoneConstants.State oldState = state; 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ringingCall.isRinging()) { 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = PhoneConstants.State.RINGING; 3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (pendingMO != null || 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville !(foregroundCall.isIdle() && backgroundCall.isIdle())) { 3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = PhoneConstants.State.OFFHOOK; 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = PhoneConstants.State.IDLE; 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (state == PhoneConstants.State.IDLE && oldState != state) { 4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville voiceCallEndedRegistrants.notifyRegistrants( 4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville new AsyncResult(null, null, null)); 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (oldState == PhoneConstants.State.IDLE && oldState != state) { 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville voiceCallStartedRegistrants.notifyRegistrants ( 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville new AsyncResult(null, null, null)); 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (state != oldState) { 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville phone.notifyPhoneStateChanged(); 4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected synchronized void 4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handlePollCalls(AsyncResult ar) { 4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville List polledCalls; 4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ar.exception == null) { 4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville polledCalls = (List)ar.result; 4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (isCommandExceptionRadioNotAvailable(ar.exception)) { 4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // just a dummy empty ArrayList to cause the loop 4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // to hang up all the calls 4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville polledCalls = new ArrayList(); 4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Radio probably wasn't ready--try again in a bit 4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // But don't keep polling if the channel is closed 4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pollCallsAfterDelay(); 4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Connection newRinging = null; //or waiting 4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean hasNonHangupStateChanged = false; // Any change besides 4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // a dropped connection 4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean needsPollDelay = false; 4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean unknownConnectionAppeared = false; 4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0, curDC = 0, dcSize = polledCalls.size() 4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ; i < connections.length; i++) { 4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmConnection conn = connections[i]; 4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville DriverCall dc = null; 4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // polledCall list is sparse 4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (curDC < dcSize) { 4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dc = (DriverCall) polledCalls.get(curDC); 4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (dc.index == i+1) { 4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville curDC++; 4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dc = null; 4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG_POLL) log("poll: conn[i=" + i + "]=" + 4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville conn+", dc=" + dc); 4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (conn == null && dc != null) { 4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Connection appeared in CLCC response that we don't know about 4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pendingMO != null && pendingMO.compareTo(dc)) { 4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG_POLL) log("poll: pendingMO=" + pendingMO); 4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // It's our pending mobile originating call 4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville connections[i] = pendingMO; 4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingMO.index = i; 4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingMO.update(dc); 4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingMO = null; 4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Someone has already asked to hangup this call 4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (hangupPendingMO) { 4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangupPendingMO = false; 4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (Phone.DEBUG_PHONE) log( 4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "poll: hangupPendingMO, hangup conn " + i); 4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangup(connections[i]); 4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (CallStateException ex) { 4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "unexpected error on hangup"); 4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Do not continue processing this poll 4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Wait for hangup and repoll 4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville connections[i] = new GsmConnection(phone.getContext(), dc, this, i); 4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // it's a ringing call 4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (connections[i].getCall() == ringingCall) { 4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville newRinging = connections[i]; 4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Something strange happened: a call appeared 4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // which is neither a ringing call or one we created. 4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Either we've crashed and re-attached to an existing 4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // call, or something else (eg, SIM) initiated the call. 4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.i(LOG_TAG,"Phantom call appeared " + dc); 4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // If it's a connected call, set the connect time so that 4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // it's non-zero. It may not be accurate, but at least 4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // it won't appear as a Missed Call. 4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (dc.state != DriverCall.State.ALERTING 4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && dc.state != DriverCall.State.DIALING) { 5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville connections[i].connectTime = System.currentTimeMillis(); 5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville unknownConnectionAppeared = true; 5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hasNonHangupStateChanged = true; 5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (conn != null && dc == null) { 5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Connection missing in CLCC response that we were 5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // tracking. 5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville droppedDuringPoll.add(conn); 5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Dropped connections are removed from the CallTracker 5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // list but kept in the GsmCall list 5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville connections[i] = null; 5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (conn != null && dc != null && !conn.compareTo(dc)) { 5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Connection in CLCC response does not match what 5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // we were tracking. Assume dropped call and new call 5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville droppedDuringPoll.add(conn); 5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville connections[i] = new GsmConnection (phone.getContext(), dc, this, i); 5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (connections[i].getCall() == ringingCall) { 5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville newRinging = connections[i]; 5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } // else something strange happened 5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hasNonHangupStateChanged = true; 5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */ 5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean changed; 5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville changed = conn.update(dc); 5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hasNonHangupStateChanged = hasNonHangupStateChanged || changed; 5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (REPEAT_POLLING) { 5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (dc != null) { 5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // FIXME with RIL, we should not need this anymore 5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((dc.state == DriverCall.State.DIALING 5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/) 5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville || (dc.state == DriverCall.State.ALERTING 5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/) 5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville || (dc.state == DriverCall.State.INCOMING 5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/) 5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville || (dc.state == DriverCall.State.WAITING 5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/) 5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ) { 5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Sometimes there's no unsolicited notification 5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // for state transitions 5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville needsPollDelay = true; 5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // This is the first poll after an ATD. 5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // We expect the pending call to appear in the list 5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // If it does not, we land here 5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pendingMO != null) { 5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.d(LOG_TAG,"Pending MO dropped before poll fg state:" 5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + foregroundCall.getState()); 5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville droppedDuringPoll.add(pendingMO); 5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingMO = null; 5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangupPendingMO = false; 5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (newRinging != null) { 5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville phone.notifyNewRingingConnection(newRinging); 5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // clear the "local hangup" and "missed/rejected call" 5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // cases from the "dropped during poll" list 5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // These cases need no "last call fail" reason 5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) { 5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmConnection conn = droppedDuringPoll.get(i); 5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (conn.isIncoming() && conn.getConnectTime() == 0) { 5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Missed or rejected call 5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Connection.DisconnectCause cause; 5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (conn.cause == Connection.DisconnectCause.LOCAL) { 5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cause = Connection.DisconnectCause.INCOMING_REJECTED; 5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cause = Connection.DisconnectCause.INCOMING_MISSED; 5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (Phone.DEBUG_PHONE) { 5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("missed/rejected call, conn.cause=" + conn.cause); 5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("setting cause to " + cause); 5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville droppedDuringPoll.remove(i); 5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville conn.onDisconnect(cause); 5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (conn.cause == Connection.DisconnectCause.LOCAL) { 5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Local hangup 5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville droppedDuringPoll.remove(i); 5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville conn.onDisconnect(Connection.DisconnectCause.LOCAL); 5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (conn.cause == 5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Connection.DisconnectCause.INVALID_NUMBER) { 5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville droppedDuringPoll.remove(i); 5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER); 5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Any non-local disconnects: determine cause 6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (droppedDuringPoll.size() > 0) { 6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.getLastCallFailCause( 6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE)); 6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (needsPollDelay) { 6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pollCallsAfterDelay(); 6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Cases when we can no longer keep disconnected Connection's 6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // with their previous calls 6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // 1) the phone has started to ring 6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // 2) A Call/Connection object has changed state... 6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // we may have switched or held or answered (but not hung up) 6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (newRinging != null || hasNonHangupStateChanged) { 6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville internalClearDisconnected(); 6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville updatePhoneState(); 6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (unknownConnectionAppeared) { 6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville phone.notifyUnknownConnection(); 6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (hasNonHangupStateChanged || newRinging != null) { 6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville phone.notifyPreciseCallStateChanged(); 6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //dumpState(); 6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void 6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleRadioNotAvailable() { 6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // handlePollCalls will clear out its 6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // call list when it gets the CommandException 6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // error result from this 6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pollCallsWhenSafe(); 6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void 6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dumpState() { 6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville List l; 6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.i(LOG_TAG,"Phone State:" + state); 6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.i(LOG_TAG,"Ringing call: " + ringingCall.toString()); 6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville l = ringingCall.getConnections(); 6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0, s = l.size(); i < s; i++) { 6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.i(LOG_TAG,l.get(i).toString()); 6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.i(LOG_TAG,"Foreground call: " + foregroundCall.toString()); 6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville l = foregroundCall.getConnections(); 6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0, s = l.size(); i < s; i++) { 6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.i(LOG_TAG,l.get(i).toString()); 6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.i(LOG_TAG,"Background call: " + backgroundCall.toString()); 6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville l = backgroundCall.getConnections(); 6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0, s = l.size(); i < s; i++) { 6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.i(LOG_TAG,l.get(i).toString()); 6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Called from GsmConnection 6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /*package*/ void 6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangup (GsmConnection conn) throws CallStateException { 6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (conn.owner != this) { 6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new CallStateException ("GsmConnection " + conn 6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "does not belong to GsmCallTracker " + this); 6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (conn == pendingMO) { 6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // We're hanging up an outgoing call that doesn't have it's 6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // GSM index assigned yet 6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true"); 6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangupPendingMO = true; 6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.hangupConnection (conn.getGSMIndex(), obtainCompleteMessage()); 6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (CallStateException ex) { 6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Ignore "connection not found" 6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Call may have hung up already 6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.w(LOG_TAG,"GsmCallTracker WARN: hangup() on absent connection " 6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + conn); 6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville conn.onHangupLocal(); 6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /*package*/ void 6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville separate (GsmConnection conn) throws CallStateException { 6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (conn.owner != this) { 7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new CallStateException ("GsmConnection " + conn 7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "does not belong to GsmCallTracker " + this); 7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.separateConnection (conn.getGSMIndex(), 7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville obtainCompleteMessage(EVENT_SEPARATE_RESULT)); 7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (CallStateException ex) { 7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Ignore "connection not found" 7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Call may have hung up already 7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.w(LOG_TAG,"GsmCallTracker WARN: separate() on absent connection " 7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + conn); 7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Called from GSMPhone 7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /*package*/ void 7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville setMute(boolean mute) { 7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville desiredMute = mute; 7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.setMute(desiredMute, null); 7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /*package*/ boolean 7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville getMute() { 7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return desiredMute; 7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Called from GsmCall 7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* package */ void 7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangup (GsmCall call) throws CallStateException { 7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (call.getConnections().size() == 0) { 7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new CallStateException("no connections in call"); 7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (call == ringingCall) { 7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background"); 7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.hangupWaitingOrBackground(obtainCompleteMessage()); 7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (call == foregroundCall) { 7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (call.isDialingOrAlerting()) { 7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (Phone.DEBUG_PHONE) { 7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("(foregnd) hangup dialing or alerting..."); 7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangup((GsmConnection)(call.getConnections().get(0))); 7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangupForegroundResumeBackground(); 7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (call == backgroundCall) { 7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ringingCall.isRinging()) { 7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (Phone.DEBUG_PHONE) { 7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("hangup all conns in background call"); 7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangupAllConnections(call); 7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville hangupWaitingOrBackground(); 7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new RuntimeException ("GsmCall " + call + 7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "does not belong to GsmCallTracker " + this); 7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville call.onHangupLocal(); 7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville phone.notifyPreciseCallStateChanged(); 7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* package */ 7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void hangupWaitingOrBackground() { 7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground"); 7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.hangupWaitingOrBackground(obtainCompleteMessage()); 7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* package */ 7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void hangupForegroundResumeBackground() { 7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground"); 7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.hangupForegroundResumeBackground(obtainCompleteMessage()); 7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void hangupConnectionByIndex(GsmCall call, int index) 7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throws CallStateException { 7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int count = call.connections.size(); 7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0; i < count; i++) { 7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmConnection cn = (GsmConnection)call.connections.get(i); 7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cn.getGSMIndex() == index) { 7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.hangupConnection(index, obtainCompleteMessage()); 7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new CallStateException("no gsm index found"); 7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void hangupAllConnections(GsmCall call) throws CallStateException{ 7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int count = call.connections.size(); 7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0; i < count; i++) { 7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmConnection cn = (GsmConnection)call.connections.get(i); 7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.hangupConnection(cn.getGSMIndex(), obtainCompleteMessage()); 7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (CallStateException ex) { 8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex); 8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* package */ 8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmConnection getConnectionByIndex(GsmCall call, int index) 8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throws CallStateException { 8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int count = call.connections.size(); 8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0; i < count; i++) { 8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmConnection cn = (GsmConnection)call.connections.get(i); 8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cn.getGSMIndex() == index) { 8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return cn; 8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private Phone.SuppService getFailedService(int what) { 8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (what) { 8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_SWITCH_RESULT: 8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Phone.SuppService.SWITCH; 8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_CONFERENCE_RESULT: 8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Phone.SuppService.CONFERENCE; 8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_SEPARATE_RESULT: 8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Phone.SuppService.SEPARATE; 8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_ECT_RESULT: 8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Phone.SuppService.TRANSFER; 8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Phone.SuppService.UNKNOWN; 8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //****** Overridden from Handler 8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void 8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleMessage (Message msg) { 8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville AsyncResult ar; 8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (msg.what) { 8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_POLL_CALLS_RESULT: 8400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult)msg.obj; 8410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (msg == lastRelevantPoll) { 8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG_POLL) log( 8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "handle EVENT_POLL_CALL_RESULT: set needsPoll=F"); 8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville needsPoll = false; 8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville lastRelevantPoll = null; 8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handlePollCalls((AsyncResult)msg.obj); 8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 8500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_OPERATION_COMPLETE: 8520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult)msg.obj; 8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville operationComplete(); 8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_SWITCH_RESULT: 8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_CONFERENCE_RESULT: 8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_SEPARATE_RESULT: 8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_ECT_RESULT: 8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult)msg.obj; 8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ar.exception != null) { 8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville phone.notifySuppServiceFailed(getFailedService(msg.what)); 8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville operationComplete(); 8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_GET_LAST_CALL_FAIL_CAUSE: 8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int causeCode; 8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult)msg.obj; 8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville operationComplete(); 8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ar.exception != null) { 8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // An exception occurred...just treat the disconnect 8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // cause as "normal" 8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville causeCode = CallFailCause.NORMAL_CLEARING; 8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.i(LOG_TAG, 8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "Exception during getLastCallFailCause, assuming normal disconnect"); 8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville causeCode = ((int[])ar.result)[0]; 8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Log the causeCode if its not normal 8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (causeCode == CallFailCause.NO_CIRCUIT_AVAIL || 8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville causeCode == CallFailCause.TEMPORARY_FAILURE || 8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville causeCode == CallFailCause.SWITCHING_CONGESTION || 8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville causeCode == CallFailCause.CHANNEL_NOT_AVAIL || 8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville causeCode == CallFailCause.QOS_NOT_AVAIL || 8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville causeCode == CallFailCause.BEARER_NOT_AVAIL || 8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville causeCode == CallFailCause.ERROR_UNSPECIFIED) { 8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation()); 8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville EventLog.writeEvent(EventLogTags.CALL_DROP, 8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville causeCode, loc != null ? loc.getCid() : -1, 8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville TelephonyManager.getDefault().getNetworkType()); 8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0, s = droppedDuringPoll.size() 8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ; i < s ; i++ 8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ) { 8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville GsmConnection conn = droppedDuringPoll.get(i); 9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville conn.onRemoteDisconnect(causeCode); 9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville updatePhoneState(); 9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville phone.notifyPreciseCallStateChanged(); 9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville droppedDuringPoll.clear(); 9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_REPOLL_AFTER_DELAY: 9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_CALL_STATE_CHANGE: 9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pollCallsWhenSafe(); 9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_RADIO_AVAILABLE: 9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleRadioAvailable(); 9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_RADIO_NOT_AVAILABLE: 9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleRadioNotAvailable(); 9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void log(String msg) { 9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.d(LOG_TAG, "[GsmCallTracker] " + msg); 9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println("GsmCallTracker extends:"); 9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville super.dump(fd, pw, args); 9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println("connections: length=" + connections.length); 9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for(int i=0; i < connections.length; i++) { 9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.printf(" connections[%d]=%s\n", i, connections[i]); 9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" voiceCallEndedRegistrants=" + voiceCallEndedRegistrants); 9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" voiceCallStartedRegistrants=" + voiceCallStartedRegistrants); 9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" droppedDuringPoll: size=" + droppedDuringPoll.size()); 9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for(int i = 0; i < droppedDuringPoll.size(); i++) { 9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.printf( " droppedDuringPoll[%d]=%s\n", i, droppedDuringPoll.get(i)); 9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" ringingCall=" + ringingCall); 9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" foregroundCall=" + foregroundCall); 9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" backgroundCall=" + backgroundCall); 9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" pendingMO=" + pendingMO); 9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" hangupPendingMO=" + hangupPendingMO); 9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" phone=" + phone); 9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" desiredMute=" + desiredMute); 9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" state=" + state); 9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 953