CallTracker.java revision befe0bf21cf06c47b1f099caed9e6c6b7125c0fe
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 66 protected void pollCallsWhenSafe() { 67 mNeedsPoll = true; 68 69 if (checkNoOperationsPending()) { 70 mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); 71 mCi.getCurrentCalls(mLastRelevantPoll); 72 } 73 } 74 75 protected void 76 pollCallsAfterDelay() { 77 Message msg = obtainMessage(); 78 79 msg.what = EVENT_REPOLL_AFTER_DELAY; 80 sendMessageDelayed(msg, POLL_DELAY_MSEC); 81 } 82 83 protected boolean 84 isCommandExceptionRadioNotAvailable(Throwable e) { 85 return e != null && e instanceof CommandException 86 && ((CommandException)e).getCommandError() 87 == CommandException.Error.RADIO_NOT_AVAILABLE; 88 } 89 90 protected abstract void handlePollCalls(AsyncResult ar); 91 92 protected void notifySrvccState(Call.SrvccState state, Connection c) { 93 if (state == Call.SrvccState.STARTED) { 94 mHandoverConnection = c; 95 } else if (state != Call.SrvccState.COMPLETED) { 96 mHandoverConnection = null; 97 } 98 } 99 100 protected void handleRadioAvailable() { 101 pollCallsWhenSafe(); 102 } 103 104 /** 105 * Obtain a complete message that indicates that this operation 106 * does not require polling of getCurrentCalls(). However, if other 107 * operations that do need getCurrentCalls() are pending or are 108 * scheduled while this operation is pending, the invocation 109 * of getCurrentCalls() will be postponed until this 110 * operation is also complete. 111 */ 112 protected Message 113 obtainNoPollCompleteMessage(int what) { 114 mPendingOperations++; 115 mLastRelevantPoll = null; 116 return obtainMessage(what); 117 } 118 119 /** 120 * @return true if we're idle or there's a call to getCurrentCalls() pending 121 * but nothing else 122 */ 123 private boolean 124 checkNoOperationsPending() { 125 if (DBG_POLL) log("checkNoOperationsPending: pendingOperations=" + 126 mPendingOperations); 127 return mPendingOperations == 0; 128 } 129 130 /** 131 * Routine called from dial to check if the number is a test Emergency number 132 * and if so remap the number. This allows a short emergency number to be remapped 133 * to a regular number for testing how the frameworks handles emergency numbers 134 * without actually calling an emergency number. 135 * 136 * This is not a full test and is not a substitute for testing real emergency 137 * numbers but can be useful. 138 * 139 * To use this feature set a system property ril.test.emergencynumber to a pair of 140 * numbers separated by a colon. If the first number matches the number parameter 141 * this routine returns the second number. Example: 142 * 143 * ril.test.emergencynumber=112:1-123-123-45678 144 * 145 * To test Dial 112 take call then hang up on MO device to enter ECM 146 * see RIL#processSolicited RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 147 * 148 * @param dialString to test if it should be remapped 149 * @return the same number or the remapped number. 150 */ 151 protected String checkForTestEmergencyNumber(String dialString) { 152 String testEn = SystemProperties.get("ril.test.emergencynumber"); 153 if (DBG_POLL) { 154 log("checkForTestEmergencyNumber: dialString=" + dialString + 155 " testEn=" + testEn); 156 } 157 if (!TextUtils.isEmpty(testEn)) { 158 String values[] = testEn.split(":"); 159 log("checkForTestEmergencyNumber: values.length=" + values.length); 160 if (values.length == 2) { 161 if (values[0].equals( 162 android.telephony.PhoneNumberUtils.stripSeparators(dialString))) { 163 mCi.testingEmergencyCall(); 164 log("checkForTestEmergencyNumber: remap " + 165 dialString + " to " + values[1]); 166 dialString = values[1]; 167 } 168 } 169 } 170 return dialString; 171 } 172 173 //***** Overridden from Handler 174 @Override 175 public abstract void handleMessage (Message msg); 176 public abstract void registerForVoiceCallStarted(Handler h, int what, Object obj); 177 public abstract void unregisterForVoiceCallStarted(Handler h); 178 public abstract void registerForVoiceCallEnded(Handler h, int what, Object obj); 179 public abstract void unregisterForVoiceCallEnded(Handler h); 180 181 protected abstract void log(String msg); 182 183 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 184 pw.println("CallTracker:"); 185 pw.println(" mPendingOperations=" + mPendingOperations); 186 pw.println(" mNeedsPoll=" + mNeedsPoll); 187 pw.println(" mLastRelevantPoll=" + mLastRelevantPoll); 188 } 189} 190