CallTracker.java revision bb097a7ba08252c516e578ce30cdb658b63d7c9b
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.telephony; 18 19import android.os.AsyncResult; 20import android.os.Handler; 21import android.os.Message; 22import android.os.SystemProperties; 23import android.text.TextUtils; 24import com.android.internal.telephony.CommandException; 25 26import java.io.FileDescriptor; 27import java.io.PrintWriter; 28 29 30/** 31 * {@hide} 32 */ 33public abstract class CallTracker extends Handler { 34 35 private static final boolean DBG_POLL = false; 36 37 //***** Constants 38 39 static final int POLL_DELAY_MSEC = 250; 40 41 protected int mPendingOperations; 42 protected boolean mNeedsPoll; 43 protected Message mLastRelevantPoll; 44 protected Connection mHandoverConnection; 45 46 public CommandsInterface mCi; 47 48 //***** Events 49 50 protected static final int EVENT_POLL_CALLS_RESULT = 1; 51 protected static final int EVENT_CALL_STATE_CHANGE = 2; 52 protected static final int EVENT_REPOLL_AFTER_DELAY = 3; 53 protected static final int EVENT_OPERATION_COMPLETE = 4; 54 protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5; 55 56 protected static final int EVENT_SWITCH_RESULT = 8; 57 protected static final int EVENT_RADIO_AVAILABLE = 9; 58 protected static final int EVENT_RADIO_NOT_AVAILABLE = 10; 59 protected static final int EVENT_CONFERENCE_RESULT = 11; 60 protected static final int EVENT_SEPARATE_RESULT = 12; 61 protected static final int EVENT_ECT_RESULT = 13; 62 protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA = 14; 63 protected static final int EVENT_CALL_WAITING_INFO_CDMA = 15; 64 protected static final int EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA = 16; 65 protected static final int EVENT_THREE_WAY_DIAL_BLANK_FLASH = 20; 66 67 protected void pollCallsWhenSafe() { 68 mNeedsPoll = true; 69 70 if (checkNoOperationsPending()) { 71 mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); 72 mCi.getCurrentCalls(mLastRelevantPoll); 73 } 74 } 75 76 protected void 77 pollCallsAfterDelay() { 78 Message msg = obtainMessage(); 79 80 msg.what = EVENT_REPOLL_AFTER_DELAY; 81 sendMessageDelayed(msg, POLL_DELAY_MSEC); 82 } 83 84 protected boolean 85 isCommandExceptionRadioNotAvailable(Throwable e) { 86 return e != null && e instanceof CommandException 87 && ((CommandException)e).getCommandError() 88 == CommandException.Error.RADIO_NOT_AVAILABLE; 89 } 90 91 protected abstract void handlePollCalls(AsyncResult ar); 92 93 protected void notifySrvccState(Call.SrvccState state, Connection c) { 94 if (state == Call.SrvccState.STARTED) { 95 mHandoverConnection = c; 96 } else if (state != Call.SrvccState.COMPLETED) { 97 mHandoverConnection = null; 98 } 99 } 100 101 protected void handleRadioAvailable() { 102 pollCallsWhenSafe(); 103 } 104 105 /** 106 * Obtain a complete message that indicates that this operation 107 * does not require polling of getCurrentCalls(). However, if other 108 * operations that do need getCurrentCalls() are pending or are 109 * scheduled while this operation is pending, the invocation 110 * of getCurrentCalls() will be postponed until this 111 * operation is also complete. 112 */ 113 protected Message 114 obtainNoPollCompleteMessage(int what) { 115 mPendingOperations++; 116 mLastRelevantPoll = null; 117 return obtainMessage(what); 118 } 119 120 /** 121 * @return true if we're idle or there's a call to getCurrentCalls() pending 122 * but nothing else 123 */ 124 private boolean 125 checkNoOperationsPending() { 126 if (DBG_POLL) log("checkNoOperationsPending: pendingOperations=" + 127 mPendingOperations); 128 return mPendingOperations == 0; 129 } 130 131 /** 132 * Routine called from dial to check if the number is a test Emergency number 133 * and if so remap the number. This allows a short emergency number to be remapped 134 * to a regular number for testing how the frameworks handles emergency numbers 135 * without actually calling an emergency number. 136 * 137 * This is not a full test and is not a substitute for testing real emergency 138 * numbers but can be useful. 139 * 140 * To use this feature set a system property ril.test.emergencynumber to a pair of 141 * numbers separated by a colon. If the first number matches the number parameter 142 * this routine returns the second number. Example: 143 * 144 * ril.test.emergencynumber=112:1-123-123-45678 145 * 146 * To test Dial 112 take call then hang up on MO device to enter ECM 147 * see RIL#processSolicited RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 148 * 149 * @param dialString to test if it should be remapped 150 * @return the same number or the remapped number. 151 */ 152 protected String checkForTestEmergencyNumber(String dialString) { 153 String testEn = SystemProperties.get("ril.test.emergencynumber"); 154 if (DBG_POLL) { 155 log("checkForTestEmergencyNumber: dialString=" + dialString + 156 " testEn=" + testEn); 157 } 158 if (!TextUtils.isEmpty(testEn)) { 159 String values[] = testEn.split(":"); 160 log("checkForTestEmergencyNumber: values.length=" + values.length); 161 if (values.length == 2) { 162 if (values[0].equals( 163 android.telephony.PhoneNumberUtils.stripSeparators(dialString))) { 164 mCi.testingEmergencyCall(); 165 log("checkForTestEmergencyNumber: remap " + 166 dialString + " to " + values[1]); 167 dialString = values[1]; 168 } 169 } 170 } 171 return dialString; 172 } 173 174 //***** Overridden from Handler 175 @Override 176 public abstract void handleMessage (Message msg); 177 public abstract void registerForVoiceCallStarted(Handler h, int what, Object obj); 178 public abstract void unregisterForVoiceCallStarted(Handler h); 179 public abstract void registerForVoiceCallEnded(Handler h, int what, Object obj); 180 public abstract void unregisterForVoiceCallEnded(Handler h); 181 182 protected abstract void log(String msg); 183 184 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 185 pw.println("CallTracker:"); 186 pw.println(" mPendingOperations=" + mPendingOperations); 187 pw.println(" mNeedsPoll=" + mNeedsPoll); 188 pw.println(" mLastRelevantPoll=" + mLastRelevantPoll); 189 } 190} 191