Merge "Send telephony notifications to appropriate users." into lmp-dev
diff --git a/res/values-mcc311-mnc220/config.xml b/res/values-mcc311-mnc220/config.xml
index 7c269e0..22701f0 100644
--- a/res/values-mcc311-mnc220/config.xml
+++ b/res/values-mcc311-mnc220/config.xml
@@ -19,4 +19,6 @@
<resources>
<!-- Flag indicating if dtmf tone type is enabled -->
<bool name="dtmf_type_enabled">true</bool>
+ <!-- CDMA activation goes through OTASP. -->
+ <bool name="config_use_otasp_for_provisioning">true</bool>
</resources>
diff --git a/res/values-mcc311-mnc580/config.xml b/res/values-mcc311-mnc580/config.xml
index 7c269e0..22701f0 100644
--- a/res/values-mcc311-mnc580/config.xml
+++ b/res/values-mcc311-mnc580/config.xml
@@ -19,4 +19,6 @@
<resources>
<!-- Flag indicating if dtmf tone type is enabled -->
<bool name="dtmf_type_enabled">true</bool>
+ <!-- CDMA activation goes through OTASP. -->
+ <bool name="config_use_otasp_for_provisioning">true</bool>
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 3daf89a..cd82234 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -127,8 +127,13 @@
<!-- Class name for the default main Dialer activity [DO NOT TRANSLATE] -->
<string name="dialer_default_class" translatable="false">com.android.dialer.DialtactsActivity</string>
- <!-- CDMA activation goes through HFA [DO NOT TRANSLATE] -->
- <bool name="config_use_hfa_for_provisioning" translatable="false">false</bool>
+ <!-- CDMA activation goes through HFA -->
+ <bool name="config_use_hfa_for_provisioning">false</bool>
+
+ <!-- CDMA activation goes through OTASP.
+ TODO: This should be combined with config_use_hfa_for_provisioning and implemented
+ as an enum (NONE, HFA, OTASP). -->
+ <bool name="config_use_otasp_for_provisioning">false</bool>
<!-- Display carrier settings menu if true -->
<bool name="config_carrier_settings_enable">false</bool>
@@ -141,4 +146,7 @@
<!-- Show APN Settings for some CDMA carriers -->
<bool name="config_show_apn_setting_cdma">false</bool>
+
+ <!-- Allows the telephony HFA logic to run even if we're not in setup wizard. -->
+ <bool name="config_allow_hfa_outside_of_setup_wizard">true</bool>
</resources>
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index b85cb7e..c38df5c 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -485,7 +485,10 @@
mAudioManager.setParameter(HAC_KEY, hac != 0 ? HAC_VAL_ON : HAC_VAL_OFF);
return true;
} else if (preference == mVoicemailSettings) {
- mVoicemailSettings.getDialog().getActionBar().setDisplayHomeAsUpEnabled(false);
+ final Dialog dialog = mVoicemailSettings.getDialog();
+ if (dialog != null) {
+ dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
+ }
if (DBG) log("onPreferenceTreeClick: Voicemail Settings Preference is clicked.");
if (preference.getIntent() != null) {
if (DBG) {
@@ -511,7 +514,10 @@
return false;
}
} else if (preference == mVoicemailSettingsScreen) {
- mVoicemailSettingsScreen.getDialog().getActionBar().setDisplayHomeAsUpEnabled(false);
+ final Dialog dialog = mVoicemailSettingsScreen.getDialog();
+ if (dialog != null) {
+ dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
+ }
return false;
}
return false;
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index be1e3b2..f22913c 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -142,8 +142,6 @@
callStateMonitor.addListener(this);
- createSignalInfoToneGenerator();
-
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
adapter.getProfileProxy(mApplication.getApplicationContext(),
@@ -944,7 +942,7 @@
@Override
public void run() {
log("SignalInfoTonePlayer.run(toneId = " + mToneId + ")...");
-
+ createSignalInfoToneGenerator();
if (mSignalInfoToneGenerator != null) {
//First stop any ongoing SignalInfo tone
mSignalInfoToneGenerator.stopTone();
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);
diff --git a/src/com/android/phone/InCallScreenShowActivation.java b/src/com/android/phone/InCallScreenShowActivation.java
index fd202db..34710a1 100644
--- a/src/com/android/phone/InCallScreenShowActivation.java
+++ b/src/com/android/phone/InCallScreenShowActivation.java
@@ -73,74 +73,81 @@
boolean usesHfa = getResources().getBoolean(R.bool.config_use_hfa_for_provisioning);
if (usesHfa) {
- Log.d(LOG_TAG, "Starting Hfa from ACTION_PERFORM_CDMA_PROVISIONING");
+ Log.i(LOG_TAG, "Starting Hfa from ACTION_PERFORM_CDMA_PROVISIONING");
startHfa();
finish();
return;
}
- // On voice-capable devices, we perform CDMA provisioning in
- // "interactive" mode by directly launching the InCallScreen.
- // boolean interactiveMode = PhoneGlobals.sVoiceCapable;
- // TODO: Renable interactive mode for device provisioning.
- boolean interactiveMode = false;
- Log.d(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
- + interactiveMode + ")...");
+ boolean usesOtasp = getResources().getBoolean(R.bool.config_use_otasp_for_provisioning);
+ if (usesOtasp) {
+ // On voice-capable devices, we perform CDMA provisioning in
+ // "interactive" mode by directly launching the InCallScreen.
+ // boolean interactiveMode = PhoneGlobals.sVoiceCapable;
+ // TODO: Renable interactive mode for device provisioning.
+ boolean interactiveMode = false;
+ Log.i(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
+ + interactiveMode + ")...");
- // Testing: this intent extra allows test apps manually
- // enable/disable "interactive mode", regardless of whether
- // the current device is voice-capable. This is allowed only
- // in userdebug or eng builds.
- if (intent.hasExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE)
- && (SystemProperties.getInt("ro.debuggable", 0) == 1)) {
- interactiveMode =
- intent.getBooleanExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE, false);
- Log.d(LOG_TAG, "===> MANUALLY OVERRIDING interactiveMode to " + interactiveMode);
- }
-
- // We allow the caller to pass a PendingIntent (as the
- // EXTRA_NONINTERACTIVE_OTASP_RESULT_PENDING_INTENT extra)
- // which we'll later use to notify them when the OTASP call
- // fails or succeeds.
- //
- // Stash that away here, and we'll fire it off later in
- // OtaUtils.sendOtaspResult().
- app.cdmaOtaScreenState.otaspResultCodePendingIntent =
- (PendingIntent) intent.getParcelableExtra(
- OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
-
- if (interactiveMode) {
- // On voice-capable devices, launch an OTASP call and arrange
- // for the in-call UI to come up. (The InCallScreen will
- // notice that an OTASP call is active, and display the
- // special OTASP UI instead of the usual in-call controls.)
-
- if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
- OtaUtils.startInteractiveOtasp(this);
-
- // The result we set here is actually irrelevant, since the
- // InCallScreen's "interactive" OTASP sequence never actually
- // finish()es; it ends by directly launching the Home
- // activity. So our caller won't actually ever get an
- // onActivityResult() call in this case.
- setResult(OtaUtils.RESULT_INTERACTIVE_OTASP_STARTED);
- } else {
- // On data-only devices, manually launch the OTASP call
- // *without* displaying any UI. (Our caller, presumably
- // SetupWizardActivity, is responsible for displaying some
- // sort of progress UI.)
-
- if (DBG) Log.d(LOG_TAG, "==> Starting non-interactive CDMA provisioning...");
- int callStatus = OtaUtils.startNonInteractiveOtasp(this);
-
- if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
- if (DBG) Log.d(LOG_TAG, " ==> successful result from startNonInteractiveOtasp(): "
- + callStatus);
- setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_STARTED);
- } else {
- Log.w(LOG_TAG, "Failure code from startNonInteractiveOtasp(): " + callStatus);
- setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_FAILED);
+ // Testing: this intent extra allows test apps manually
+ // enable/disable "interactive mode", regardless of whether
+ // the current device is voice-capable. This is allowed only
+ // in userdebug or eng builds.
+ if (intent.hasExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE)
+ && (SystemProperties.getInt("ro.debuggable", 0) == 1)) {
+ interactiveMode =
+ intent.getBooleanExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE, false);
+ Log.d(LOG_TAG, "==> MANUALLY OVERRIDING interactiveMode to " + interactiveMode);
}
+
+ // We allow the caller to pass a PendingIntent (as the
+ // EXTRA_NONINTERACTIVE_OTASP_RESULT_PENDING_INTENT extra)
+ // which we'll later use to notify them when the OTASP call
+ // fails or succeeds.
+ //
+ // Stash that away here, and we'll fire it off later in
+ // OtaUtils.sendOtaspResult().
+ app.cdmaOtaScreenState.otaspResultCodePendingIntent =
+ (PendingIntent) intent.getParcelableExtra(
+ OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
+
+ if (interactiveMode) {
+ // On voice-capable devices, launch an OTASP call and arrange
+ // for the in-call UI to come up. (The InCallScreen will
+ // notice that an OTASP call is active, and display the
+ // special OTASP UI instead of the usual in-call controls.)
+
+ if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
+ OtaUtils.startInteractiveOtasp(this);
+
+ // The result we set here is actually irrelevant, since the
+ // InCallScreen's "interactive" OTASP sequence never actually
+ // finish()es; it ends by directly launching the Home
+ // activity. So our caller won't actually ever get an
+ // onActivityResult() call in this case.
+ setResult(OtaUtils.RESULT_INTERACTIVE_OTASP_STARTED);
+ } else {
+ // On data-only devices, manually launch the OTASP call
+ // *without* displaying any UI. (Our caller, presumably
+ // SetupWizardActivity, is responsible for displaying some
+ // sort of progress UI.)
+
+ if (DBG) Log.d(LOG_TAG, "==> Starting non-interactive CDMA provisioning...");
+ int callStatus = OtaUtils.startNonInteractiveOtasp(this);
+
+ if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
+ if (DBG) Log.d(LOG_TAG,
+ " ==> successful result from startNonInteractiveOtasp(): " +
+ callStatus);
+ setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_STARTED);
+ } else {
+ Log.w(LOG_TAG, "Failure code from startNonInteractiveOtasp(): " +
+ callStatus);
+ setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_FAILED);
+ }
+ }
+ } else {
+ Log.i(LOG_TAG, "Skipping activation.");
}
} else {
Log.e(LOG_TAG, "Unexpected intent action: " + intent);
@@ -180,28 +187,34 @@
* Starts the HFA provisioning process by bringing up the HFA Activity.
*/
private void startHfa() {
- final Intent intent = new Intent();
+ boolean isWizardRunning = isWizardRunning(this);
+ // We always run our HFA logic if we're in setup wizard, but if we're outside of setup
+ // wizard then we have to check a config to see if we should still run HFA.
+ if (isWizardRunning ||
+ getResources().getBoolean(R.bool.config_allow_hfa_outside_of_setup_wizard)) {
- final PendingIntent otaResponseIntent = getIntent().getParcelableExtra(
- OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
+ final Intent intent = new Intent();
- final boolean showUi = !isWizardRunning(this);
+ final PendingIntent otaResponseIntent = getIntent().getParcelableExtra(
+ OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ final boolean showUi = !isWizardRunning;
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (otaResponseIntent != null) {
- intent.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT, otaResponseIntent);
+ if (otaResponseIntent != null) {
+ intent.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT, otaResponseIntent);
+ }
+
+ Log.v(LOG_TAG, "Starting hfa activation activity");
+ if (showUi) {
+ intent.setClassName(this, HfaActivity.class.getName());
+ startActivity(intent);
+ } else {
+ intent.setClassName(this, HfaService.class.getName());
+ startService(intent);
+ }
+
}
-
- Log.v(LOG_TAG, "Starting hfa activation activity");
- if (showUi) {
- intent.setClassName(this, HfaActivity.class.getName());
- startActivity(intent);
- } else {
- intent.setClassName(this, HfaService.class.getName());
- startService(intent);
- }
-
setResult(RESULT_OK);
}
}
diff --git a/src/com/android/services/telephony/PstnIncomingCallNotifier.java b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
index 654150c..f4c8a22 100644
--- a/src/com/android/services/telephony/PstnIncomingCallNotifier.java
+++ b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
@@ -197,6 +197,10 @@
private void handleNewUnknownConnection(AsyncResult asyncResult) {
Log.i(this, "handleNewUnknownConnection");
+ if (!(asyncResult.result instanceof Connection)) {
+ Log.w(this, "handleNewUnknownConnection called with non-Connection object");
+ return;
+ }
Connection connection = (Connection) asyncResult.result;
if (connection != null) {
Call call = connection.getCall();
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index e8c148a..73a57d3 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -84,6 +84,13 @@
// TODO: We don't check for SecurityException here (requires
// CALL_PRIVILEGED permission).
final Phone phone = getPhoneForAccount(request.getAccountHandle(), false);
+ if (phone == null) {
+ Log.d(this, "onCreateOutgoingConnection, phone is null");
+ return Connection.createFailedConnection(
+ DisconnectCauseUtil.toTelecomDisconnectCause(
+ android.telephony.DisconnectCause.OUTGOING_FAILURE,
+ "Phone is null"));
+ }
number = phone.getVoiceMailNumber();
if (TextUtils.isEmpty(number)) {
Log.d(this, "onCreateOutgoingConnection, no voicemail number set.");