summaryrefslogtreecommitdiffstats
path: root/telephony/java
diff options
context:
space:
mode:
authorWink Saville <wink@google.com>2009-08-18 12:08:59 -0700
committerWink Saville <wink@google.com>2009-08-18 12:08:59 -0700
commit95a1d1a89e383dab893750638c2393dec54833ff (patch)
tree57d7106336e1cee68373421ff4f7cd454ba00d96 /telephony/java
parent6a2d513a4ad116fc5405d4d4f1f6fdb692bdefbc (diff)
downloadframeworks_base-95a1d1a89e383dab893750638c2393dec54833ff.zip
frameworks_base-95a1d1a89e383dab893750638c2393dec54833ff.tar.gz
frameworks_base-95a1d1a89e383dab893750638c2393dec54833ff.tar.bz2
E911 call fix in ECM
Based on the VZW requirement, phone should be still in ECM mode in 2nd emergency call. but in the current phone call, if a 2nd emergency call is originated, ECM mode will exit. For fixing this problem, the coding design is as below: 1. In framework, canceling the first ECM timer immediately upon the origination of the 2nd E911 call, and restarting a new timer when the 2nd E911 ends. 2. Framework needs to syncronize the timer with phone app by sending notification to phone app to inform timer is canceled or re-started, since phone app needs to show how much ECM time left on the status bar. 3. In phone app's emergency callback mode service, the timer in this service will be canceled when it receives the timer cancel notification from framework; the timer will be restarted once it receives timer restart notification from framework.
Diffstat (limited to 'telephony/java')
-rw-r--r--telephony/java/com/android/internal/telephony/Phone.java14
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java10
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneProxy.java8
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CDMAPhone.java107
-rwxr-xr-x[-rw-r--r--]telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java49
5 files changed, 158 insertions, 30 deletions
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 622b47d..3f9744f 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -434,6 +434,20 @@ public interface Phone {
void unregisterForMmiComplete(Handler h);
/**
+ * Registration point for Ecm timer reset
+ * @param h handler to notify
+ * @param what user-defined message code
+ * @param obj placed in Message.obj
+ */
+ public void registerForEcmTimerReset(Handler h, int what, Object obj);
+
+ /**
+ * Unregister for notification for Ecm timer reset
+ * @param h Handler to be removed from the registrant list.
+ */
+ public void unregisterForEcmTimerReset(Handler h);
+
+ /**
* Returns a list of MMI codes that are pending. (They have initiated
* but have not yet completed).
* Presently there is only ever one.
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 6f4aef9..04a3749 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -760,6 +760,16 @@ public abstract class PhoneBase implements Phone {
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
}
+ public void registerForEcmTimerReset(Handler h, int what, Object obj) {
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
+
+ public void unregisterForEcmTimerReset(Handler h) {
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
+
public void registerForSignalInfo(Handler h, int what, Object obj) {
mCM.registerForSignalInfo(h, what, obj);
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index f2568c1..8683278 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -323,6 +323,14 @@ public class PhoneProxy extends Handler implements Phone {
mActivePhone.unregisterForSubscriptionInfoReady(h);
}
+ public void registerForEcmTimerReset(Handler h, int what, Object obj) {
+ mActivePhone.registerForEcmTimerReset(h,what,obj);
+ }
+
+ public void unregisterForEcmTimerReset(Handler h) {
+ mActivePhone.unregisterForEcmTimerReset(h);
+ }
+
public boolean getIccRecordsLoaded() {
return mActivePhone.getIccRecordsLoaded();
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index f0c0ea2..237d533 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -28,6 +28,8 @@ import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.RemoteException;
@@ -72,8 +74,7 @@ import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OP
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
+
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -87,10 +88,14 @@ public class CDMAPhone extends PhoneBase {
// Default Emergency Callback Mode exit timer
private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 300000;
+
static final String VM_COUNT_CDMA = "vm_count_key_cdma";
private static final String VM_NUMBER_CDMA = "vm_number_key_cdma";
private String mVmNumber = null;
+ static final int RESTART_ECM_TIMER = 0; // restart Ecm timer
+ static final int CANCEL_ECM_TIMER = 1; // cancel Ecm timer
+
//***** Instance Variables
CdmaCallTracker mCT;
CdmaSMSDispatcher mSMS;
@@ -103,6 +108,7 @@ public class CDMAPhone extends PhoneBase {
RuimSmsInterfaceManager mRuimSmsInterfaceManager;
PhoneSubInfo mSubInfo;
EriManager mEriManager;
+ WakeLock mWakeLock;
// mNvLoadedRegistrants are informed after the EVENT_NV_READY
private RegistrantList mNvLoadedRegistrants = new RegistrantList();
@@ -110,17 +116,20 @@ public class CDMAPhone extends PhoneBase {
// mEriFileLoadedRegistrants are informed after the ERI text has been loaded
private RegistrantList mEriFileLoadedRegistrants = new RegistrantList();
- // mECMExitRespRegistrant is informed after the phone has been exited
+ // mEcmTimerResetRegistrants are informed after Ecm timer is canceled or re-started
+ private RegistrantList mEcmTimerResetRegistrants = new RegistrantList();
+
+ // mEcmExitRespRegistrant is informed after the phone has been exited
//the emergency callback mode
//keep track of if phone is in emergency callback mode
- private boolean mIsPhoneInECMState;
- private Registrant mECMExitRespRegistrant;
+ private boolean mIsPhoneInEcmState;
+ private Registrant mEcmExitRespRegistrant;
private String mEsn;
private String mMeid;
// string to define how the carrier specifies its own ota sp number
private String mCarrierOtaSpNumSchema;
- // A runnable which is used to automatically exit from ECM after a period of time.
+ // A runnable which is used to automatically exit from Ecm after a period of time.
private Runnable mExitEcmRunnable = new Runnable() {
public void run() {
exitEmergencyCallbackMode();
@@ -165,6 +174,9 @@ public class CDMAPhone extends PhoneBase {
mCM.registerForNVReady(h, EVENT_NV_READY, null);
mCM.setEmergencyCallbackMode(h, EVENT_EMERGENCY_CALLBACK_MODE_ENTER, null);
+ PowerManager pm
+ = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,LOG_TAG);
//Change the system setting
SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
@@ -172,7 +184,7 @@ public class CDMAPhone extends PhoneBase {
// This is needed to handle phone process crashes
String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
- mIsPhoneInECMState = inEcm.equals("true");
+ mIsPhoneInEcmState = inEcm.equals("true");
// get the string that specifies the carrier OTA Sp number
mCarrierOtaSpNumSchema = SystemProperties.get(
@@ -244,6 +256,10 @@ public class CDMAPhone extends PhoneBase {
protected void finalize() {
if(DBG) Log.d(LOG_TAG, "CDMAPhone finalized");
+ if (mWakeLock.isHeld()) {
+ Log.e(LOG_TAG, "UNEXPECTED; mWakeLock is held when finalizing.");
+ mWakeLock.release();
+ }
}
@@ -525,11 +541,11 @@ public class CDMAPhone extends PhoneBase {
}
public void setOnEcbModeExitResponse(Handler h, int what, Object obj) {
- mECMExitRespRegistrant = new Registrant (h, what, obj);
+ mEcmExitRespRegistrant = new Registrant (h, what, obj);
}
public void unsetOnEcbModeExitResponse(Handler h) {
- mECMExitRespRegistrant.clear();
+ mEcmExitRespRegistrant.clear();
}
public void registerForCallWaiting(Handler h, int what, Object obj) {
@@ -729,7 +745,7 @@ public class CDMAPhone extends PhoneBase {
public boolean enableDataConnectivity() {
// block data activities when phone is in emergency callback mode
- if (mIsPhoneInECMState) {
+ if (mIsPhoneInEcmState) {
Intent intent = new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS);
ActivityManagerNative.broadcastStickyIntent(intent, null);
return false;
@@ -826,8 +842,9 @@ public class CDMAPhone extends PhoneBase {
void sendEmergencyCallbackModeChange(){
//Send an Intent
Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
- intent.putExtra(PHONE_IN_ECM_STATE, mIsPhoneInECMState);
+ intent.putExtra(PHONE_IN_ECM_STATE, mIsPhoneInEcmState);
ActivityManagerNative.broadcastStickyIntent(intent,null);
+ if (DBG) Log.d(LOG_TAG, "sendEmergencyCallbackModeChange");
}
/*package*/ void
@@ -859,15 +876,21 @@ public class CDMAPhone extends PhoneBase {
@Override
public void exitEmergencyCallbackMode() {
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
// Send a message which will invoke handleExitEmergencyCallbackMode
mCM.exitEmergencyCallbackMode(h.obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE));
}
private void handleEnterEmergencyCallbackMode(Message msg) {
- Log.d(LOG_TAG, "Event EVENT_EMERGENCY_CALLBACK_MODE Received");
- // if phone is not in ECM mode, and it's changed to ECM mode
- if (mIsPhoneInECMState == false) {
- mIsPhoneInECMState = true;
+ if (DBG) {
+ Log.d(LOG_TAG, "handleEnterEmergencyCallbackMode,mIsPhoneInEcmState= "
+ + mIsPhoneInEcmState);
+ }
+ // if phone is not in Ecm mode, and it's changed to Ecm mode
+ if (mIsPhoneInEcmState == false) {
+ mIsPhoneInEcmState = true;
// notify change
sendEmergencyCallbackModeChange();
setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true");
@@ -877,23 +900,27 @@ public class CDMAPhone extends PhoneBase {
long delayInMillis = SystemProperties.getLong(
TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE);
h.postDelayed(mExitEcmRunnable, delayInMillis);
+ // We don't want to go to sleep while in Ecm
+ mWakeLock.acquire();
}
}
private void handleExitEmergencyCallbackMode(Message msg) {
- Log.d(LOG_TAG, "Event EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE Received");
AsyncResult ar = (AsyncResult)msg.obj;
-
- // Remove pending exit ECM runnable, if any
+ if (DBG) {
+ Log.d(LOG_TAG, "handleExitEmergencyCallbackMode,ar.exception , mIsPhoneInEcmState "
+ + ar.exception + mIsPhoneInEcmState);
+ }
+ // Remove pending exit Ecm runnable, if any
h.removeCallbacks(mExitEcmRunnable);
- if (mECMExitRespRegistrant != null) {
- mECMExitRespRegistrant.notifyRegistrant(ar);
+ if (mEcmExitRespRegistrant != null) {
+ mEcmExitRespRegistrant.notifyRegistrant(ar);
}
// if exiting ecm success
if (ar.exception == null) {
- if (mIsPhoneInECMState) {
- mIsPhoneInECMState = false;
+ if (mIsPhoneInEcmState) {
+ mIsPhoneInEcmState = false;
setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false");
}
// send an Intent
@@ -903,6 +930,42 @@ public class CDMAPhone extends PhoneBase {
}
}
+ /**
+ * Handle to cancel or restart Ecm timer in emergency call back mode
+ * if action is CANCEL_ECM_TIMER, cancel Ecm timer and notify apps the timer is canceled;
+ * otherwise, restart Ecm timer and notify apps the timer is restarted.
+ */
+ void handleTimerInEmergencyCallbackMode(int action) {
+ switch(action) {
+ case CANCEL_ECM_TIMER:
+ h.removeCallbacks(mExitEcmRunnable);
+ mEcmTimerResetRegistrants.notifyResult(new Boolean(true));
+ break;
+ case RESTART_ECM_TIMER:
+ long delayInMillis = SystemProperties.getLong(
+ TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE);
+ h.postDelayed(mExitEcmRunnable, delayInMillis);
+ mEcmTimerResetRegistrants.notifyResult(new Boolean(false));
+ break;
+ default:
+ Log.e(LOG_TAG, "handleTimerInEmergencyCallbackMode, unsupported action " + action);
+ }
+ }
+
+ /**
+ * Registration point for Ecm timer reset
+ * @param h handler to notify
+ * @param what User-defined message code
+ * @param obj placed in Message.obj
+ */
+ public void registerForEcmTimerReset(Handler h, int what, Object obj) {
+ mEcmTimerResetRegistrants.addUnique(h, what, obj);
+ }
+
+ public void unregisterForEcmTimerReset(Handler h) {
+ mEcmTimerResetRegistrants.remove(h);
+ }
+
//***** Inner Classes
class MyHandler extends Handler {
MyHandler() {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index be4763c..7bbf91d 100644..100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -72,7 +72,7 @@ public final class CdmaCallTracker extends CallTracker {
CdmaConnection pendingMO;
boolean hangupPendingMO;
- boolean pendingCallInECM=false;
+ boolean pendingCallInEcm=false;
CDMAPhone phone;
boolean desiredMute = false; // false = mute off
@@ -80,6 +80,7 @@ public final class CdmaCallTracker extends CallTracker {
int pendingCallClirMode;
Phone.State state = Phone.State.IDLE;
+ private boolean mIsEcmTimerCanceled = false;
// boolean needsPoll;
@@ -182,6 +183,14 @@ public final class CdmaCallTracker extends CallTracker {
throw new CallStateException("cannot dial in current state");
}
+ String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
+ boolean isPhoneInEcmMode = inEcm.equals("true");
+ boolean isEmergencyCall = PhoneNumberUtils.isEmergencyNumber(dialString);
+
+ // Cancel Ecm timer if a second emergency call is originating in Ecm mode
+ if (isPhoneInEcmMode && isEmergencyCall) {
+ handleEcmTimer(phone.CANCEL_ECM_TIMER);
+ }
// We are initiating a call therefore even if we previously
// didn't know the state (i.e. Generic was true) we now know
@@ -210,14 +219,14 @@ public final class CdmaCallTracker extends CallTracker {
// Always unmute when initiating a new call
setMute(false);
- String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
- if(inEcm.equals("false")) {
+ // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
+ if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
} else {
phone.exitEmergencyCallbackMode();
phone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
pendingCallClirMode=clirMode;
- pendingCallInECM=true;
+ pendingCallInEcm=true;
}
}
@@ -479,6 +488,11 @@ public final class CdmaCallTracker extends CallTracker {
// Someone has already asked to hangup this call
if (hangupPendingMO) {
hangupPendingMO = false;
+ // Re-start Ecm timer when an uncompleted emergency call ends
+ if (mIsEcmTimerCanceled) {
+ handleEcmTimer(phone.RESTART_ECM_TIMER);
+ }
+
try {
if (Phone.DEBUG_PHONE) log(
"poll: hangupPendingMO, hangup conn " + i);
@@ -532,6 +546,12 @@ public final class CdmaCallTracker extends CallTracker {
}
}
foregroundCall.setGeneric(false);
+
+ // Re-start Ecm timer when the connected emergency call ends
+ if (mIsEcmTimerCanceled) {
+ handleEcmTimer(phone.RESTART_ECM_TIMER);
+ }
+
// Dropped connections are removed from the CallTracker
// list but kept in the Call list
connections[i] = null;
@@ -571,8 +591,8 @@ public final class CdmaCallTracker extends CallTracker {
droppedDuringPoll.add(pendingMO);
pendingMO = null;
hangupPendingMO = false;
- if( pendingCallInECM) {
- pendingCallInECM = false;
+ if( pendingCallInEcm) {
+ pendingCallInEcm = false;
}
}
@@ -941,9 +961,9 @@ public final class CdmaCallTracker extends CallTracker {
case EVENT_EXIT_ECM_RESPONSE_CDMA:
//no matter the result, we still do the same here
- if (pendingCallInECM) {
+ if (pendingCallInEcm) {
cm.dial(pendingMO.address, pendingCallClirMode, obtainCompleteMessage());
- pendingCallInECM = false;
+ pendingCallInEcm = false;
}
phone.unsetOnEcbModeExitResponse(this);
break;
@@ -971,6 +991,19 @@ public final class CdmaCallTracker extends CallTracker {
}
}
+ /**
+ * Handle Ecm timer to be canceled or re-started
+ */
+ private void handleEcmTimer(int action) {
+ phone.handleTimerInEmergencyCallbackMode(action);
+ switch(action) {
+ case CDMAPhone.CANCEL_ECM_TIMER: mIsEcmTimerCanceled = true; break;
+ case CDMAPhone.RESTART_ECM_TIMER: mIsEcmTimerCanceled = false; break;
+ default:
+ Log.e(LOG_TAG, "handleEcmTimer, unsupported action " + action);
+ }
+ }
+
protected void log(String msg) {
Log.d(LOG_TAG, "[CdmaCallTracker] " + msg);
}