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; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties; 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.text.TextUtils; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log; 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandException; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor; 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter; 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide} 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic abstract class CallTracker extends Handler { 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final boolean DBG_POLL = false; 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Constants 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int POLL_DELAY_MSEC = 250; 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected int pendingOperations; 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected boolean needsPoll; 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected Message lastRelevantPoll; 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public CommandsInterface cm; 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Events 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_POLL_CALLS_RESULT = 1; 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_CALL_STATE_CHANGE = 2; 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_REPOLL_AFTER_DELAY = 3; 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_OPERATION_COMPLETE = 4; 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5; 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_SWITCH_RESULT = 8; 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_RADIO_AVAILABLE = 9; 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_RADIO_NOT_AVAILABLE = 10; 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_CONFERENCE_RESULT = 11; 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_SEPARATE_RESULT = 12; 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_ECT_RESULT = 13; 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA = 14; 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_CALL_WAITING_INFO_CDMA = 15; 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected static final int EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA = 16; 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void pollCallsWhenSafe() { 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville needsPoll = true; 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (checkNoOperationsPending()) { 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.getCurrentCalls(lastRelevantPoll); 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pollCallsAfterDelay() { 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message msg = obtainMessage(); 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.what = EVENT_REPOLL_AFTER_DELAY; 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendMessageDelayed(msg, POLL_DELAY_MSEC); 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected boolean 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville isCommandExceptionRadioNotAvailable(Throwable e) { 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return e != null && e instanceof CommandException 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && ((CommandException)e).getCommandError() 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville == CommandException.Error.RADIO_NOT_AVAILABLE; 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected abstract void handlePollCalls(AsyncResult ar); 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void handleRadioAvailable() { 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pollCallsWhenSafe(); 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Obtain a complete message that indicates that this operation 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * does not require polling of getCurrentCalls(). However, if other 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * operations that do need getCurrentCalls() are pending or are 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * scheduled while this operation is pending, the invocation 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * of getCurrentCalls() will be postponed until this 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * operation is also complete. 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected Message 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville obtainNoPollCompleteMessage(int what) { 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingOperations++; 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville lastRelevantPoll = null; 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return obtainMessage(what); 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if we're idle or there's a call to getCurrentCalls() pending 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * but nothing else 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville checkNoOperationsPending() { 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG_POLL) log("checkNoOperationsPending: pendingOperations=" + 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pendingOperations); 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return pendingOperations == 0; 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Routine called from dial to check if the number is a test Emergency number 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and if so remap the number. This allows a short emergency number to be remapped 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * to a regular number for testing how the frameworks handles emergency numbers 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * without actually calling an emergency number. 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This is not a full test and is not a substitute for testing real emergency 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * numbers but can be useful. 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * To use this feature set a system property ril.test.emergencynumber to a pair of 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * numbers separated by a colon. If the first number matches the number parameter 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * this routine returns the second number. Example: 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * ril.test.emergencynumber=112:1-123-123-45678 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * To test Dial 112 take call then hang up on MO device to enter ECM 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * see RIL#processSolicited RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param number to test if it should be remapped 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the same number or the remapped number. 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected String checkForTestEmergencyNumber(String dialString) { 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String testEn = SystemProperties.get("ril.test.emergencynumber"); 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG_POLL) { 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("checkForTestEmergencyNumber: dialString=" + dialString + 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville " testEn=" + testEn); 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!TextUtils.isEmpty(testEn)) { 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String values[] = testEn.split(":"); 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("checkForTestEmergencyNumber: values.length=" + values.length); 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (values.length == 2) { 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (values[0].equals( 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville android.telephony.PhoneNumberUtils.stripSeparators(dialString))) { 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cm.testingEmergencyCall(); 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("checkForTestEmergencyNumber: remap " + 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dialString + " to " + values[1]); 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dialString = values[1]; 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return dialString; 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Overridden from Handler 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public abstract void handleMessage (Message msg); 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public abstract void registerForVoiceCallStarted(Handler h, int what, Object obj); 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public abstract void unregisterForVoiceCallStarted(Handler h); 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public abstract void registerForVoiceCallEnded(Handler h, int what, Object obj); 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public abstract void unregisterForVoiceCallEnded(Handler h); 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected abstract void log(String msg); 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println("CallTracker:"); 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" pendingOperations=" + pendingOperations); 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" needsPoll=" + needsPoll); 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pw.println(" lastRelevantPoll=" + lastRelevantPoll); 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 183