Fix ECM issues
Fix crash in EmergencyCallbackModeExitDialog
* Return immediately if not in ECM and don't register receivers/show dialog
* Add more logging to diagnose future issues
Make sure ECM notification doesn't show up if emergency call is dialed twice
and then ECM mode dismissed.
* Fixed a timer leak that was causing the ECM notification to be posted
constantly even if we were out of ECM. This happens if ECMService has
startTimerNotification called and mTimer is not previously null.
* As a safeguard, if showNotification is called and we are already out of ECM,
stop the service.
Bug: 17958545
Change-Id: Ife3117eba2a750bc6a8e9cb59f3b5f55d563409a
diff --git a/src/com/android/phone/EmergencyCallbackModeExitDialog.java b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
index 921b7f7..7f4bd1b 100644
--- a/src/com/android/phone/EmergencyCallbackModeExitDialog.java
+++ b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
@@ -50,6 +50,8 @@
*/
public class EmergencyCallbackModeExitDialog extends Activity implements OnDismissListener {
+ private static final String TAG = "EmergencyCallbackMode";
+
/** Intent to trigger the Emergency Callback Mode exit dialog */
static final String ACTION_SHOW_ECM_EXIT_DIALOG =
"com.android.phone.action.ACTION_SHOW_ECM_EXIT_DIALOG";
@@ -77,9 +79,12 @@
super.onCreate(savedInstanceState);
// Check if phone is in Emergency Callback Mode. If not, exit.
- if (!Boolean.parseBoolean(
- SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
+ final boolean isInEcm = Boolean.parseBoolean(
+ SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE));
+ Log.i(TAG, "ECMModeExitDialog launched - isInEcm: " + isInEcm);
+ if (!isInEcm) {
finish();
+ return;
}
mHandler = new Handler();
@@ -103,9 +108,15 @@
@Override
public void onDestroy() {
super.onDestroy();
- unregisterReceiver(mEcmExitReceiver);
+ try {
+ unregisterReceiver(mEcmExitReceiver);
+ } catch (IllegalArgumentException e) {
+ // Receiver was never registered - silently ignore.
+ }
// Unregister ECM timer reset notification
- mPhone.unregisterForEcmTimerReset(mHandler);
+ if (mPhone != null) {
+ mPhone.unregisterForEcmTimerReset(mHandler);
+ }
}
@Override
@@ -148,11 +159,16 @@
if (mService != null) {
mEcmTimeout = mService.getEmergencyCallbackModeTimeout();
mInEmergencyCall = mService.getEmergencyCallbackModeCallState();
+ try {
+ // Unbind from remote service
+ unbindService(mConnection);
+ } catch (IllegalArgumentException e) {
+ // Failed to unbind from service. Don't crash as this brings down the entire
+ // radio.
+ Log.w(TAG, "Failed to unbind from EmergencyCallbackModeService");
+ }
}
- // Unbind from remote service
- unbindService(mConnection);
-
// Show dialog
mHandler.post(new Runnable() {
public void run() {
@@ -166,7 +182,10 @@
* Shows Emergency Callback Mode dialog and starts countdown timer
*/
private void showEmergencyCallbackModeExitDialog() {
-
+ if (!this.isResumed()) {
+ Log.w(TAG, "Tried to show dialog, but activity was already finished");
+ return;
+ }
if(mInEmergencyCall) {
mDialogType = EXIT_ECM_IN_EMERGENCY_CALL_DIALOG;
showDialog(EXIT_ECM_IN_EMERGENCY_CALL_DIALOG);
@@ -283,6 +302,7 @@
/**
* Closes activity when dialog is dismissed
*/
+ @Override
public void onDismiss(DialogInterface dialog) {
EmergencyCallbackModeExitDialog.this.setResult(RESULT_OK, (new Intent())
.putExtra(EXTRA_EXIT_ECM_RESULT, false));
diff --git a/src/com/android/phone/EmergencyCallbackModeService.java b/src/com/android/phone/EmergencyCallbackModeService.java
index e1f7fb3..3310df1 100644
--- a/src/com/android/phone/EmergencyCallbackModeService.java
+++ b/src/com/android/phone/EmergencyCallbackModeService.java
@@ -144,26 +144,40 @@
showNotification(ecmTimeout);
// Start countdown timer for the notification updates
- mTimer = new CountDownTimer(ecmTimeout, 1000) {
+ if (mTimer != null) {
+ mTimer.cancel();
+ } else {
+ mTimer = new CountDownTimer(ecmTimeout, 1000) {
- @Override
- public void onTick(long millisUntilFinished) {
- mTimeLeft = millisUntilFinished;
- EmergencyCallbackModeService.this.showNotification(millisUntilFinished);
- }
+ @Override
+ public void onTick(long millisUntilFinished) {
+ mTimeLeft = millisUntilFinished;
+ EmergencyCallbackModeService.this.showNotification(millisUntilFinished);
+ }
- @Override
- public void onFinish() {
- //Do nothing
- }
+ @Override
+ public void onFinish() {
+ //Do nothing
+ }
- }.start();
+ };
+ }
+ mTimer.start();
}
/**
* Shows notification for Emergency Callback Mode
*/
private void showNotification(long millisUntilFinished) {
+ final boolean isInEcm = Boolean.parseBoolean(
+ SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE));
+ if (!isInEcm) {
+ Log.i(LOG_TAG, "Asked to show notification but not in ECM mode");
+ if (mTimer != null) {
+ mTimer.cancel();
+ }
+ return;
+ }
final Notification.Builder builder = new Notification.Builder(getApplicationContext());
builder.setOngoing(true);
builder.setPriority(Notification.PRIORITY_HIGH);