Merge "Handle when non-emergency call fails and no 2G" into main
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 61143c9..972e7cb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1206,8 +1206,13 @@
<string name="incall_error_emergency_only">Not registered on network.</string>
<!-- In-call screen: call failure message displayed in an error dialog -->
<string name="incall_error_out_of_service">Mobile network not available.</string>
+ <!-- In-call screen: call failure message displayed in an error dialog if 2G is disabled -->
+ <string name="incall_error_out_of_service_2g">Mobile network not available.\n\nConnect to a wireless network to make a call.\n\n2G is disabled on this device, which may be impacting your connectivity. Go to Settings and enable "Allow 2G" to continue.</string>
<!-- In-call screen: call failure message displayed in an error dialog -->
<string name="incall_error_out_of_service_wfc">Mobile network is not available. Connect to a wireless network to make a call.</string>
+ <!-- In-call screen: call failure message displayed in an error dialog if the user disabled 2G -->
+ <string name="incall_error_out_of_service_wfc_2g_user">Mobile network is not available.\n\nConnect to a wireless network to make a call.\n\n2G is disabled on this device, which may be impacting your connectivity. Go to Settings and enable "Allow 2G" to continue.</string>
+
<!-- In-call screen: call failure message displayed in an error dialog -->
<string name="incall_error_no_phone_number_supplied">To place a call, enter a valid number.</string>
<!-- In-call screen: call failure message displayed in an error dialog -->
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index c00adef..ddcb5aa 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -23,12 +23,15 @@
import android.telecom.DisconnectCause;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.telephony.ims.ImsReasonInfo;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CallFailCause;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.internal.telephony.flags.FeatureFlagsImpl;
import com.android.phone.ImsUtil;
import com.android.phone.PhoneGlobals;
import com.android.phone.R;
@@ -86,7 +89,7 @@
public static DisconnectCause toTelecomDisconnectCause(int telephonyDisconnectCause,
String reason, int phoneId) {
return toTelecomDisconnectCause(telephonyDisconnectCause, CallFailCause.NOT_VALID,
- reason, phoneId, null, new FlagsAdapterImpl());
+ reason, phoneId, null, new FlagsAdapterImpl(), false);
}
/**
@@ -103,7 +106,27 @@
int telephonyDisconnectCause, int telephonyPreciseDisconnectCause, String reason,
int phoneId, ImsReasonInfo imsReasonInfo, FlagsAdapter featureFlags) {
return toTelecomDisconnectCause(telephonyDisconnectCause, telephonyPreciseDisconnectCause,
- reason, phoneId, imsReasonInfo, getCarrierConfigBundle(phoneId), featureFlags);
+ reason, phoneId, imsReasonInfo, getCarrierConfigBundle(phoneId), featureFlags,
+ false);
+ }
+
+ /**
+ * Converts from a disconnect code in {@link android.telephony.DisconnectCause} into a more
+ * generic {@link android.telecom.DisconnectCause}.object, possibly populated with a localized
+ * message and tone for Slot.
+ * @param telephonyDisconnectCause The code for the reason for the disconnect.
+ * @param telephonyPreciseDisconnectCause The code for the precise reason for the disconnect.
+ * @param reason Description of the reason for the disconnect, not intended for the user to see.
+ * @param phoneId To support localized message based on phoneId
+ * @param imsReasonInfo
+ */
+ public static DisconnectCause toTelecomDisconnectCause(
+ int telephonyDisconnectCause, int telephonyPreciseDisconnectCause, String reason,
+ int phoneId, ImsReasonInfo imsReasonInfo, FlagsAdapter featureFlags,
+ boolean shouldTreatAsEmergency) {
+ return toTelecomDisconnectCause(telephonyDisconnectCause, telephonyPreciseDisconnectCause,
+ reason, phoneId, imsReasonInfo, getCarrierConfigBundle(phoneId), featureFlags,
+ shouldTreatAsEmergency);
}
/**
@@ -116,7 +139,7 @@
static DisconnectCause toTelecomDisconnectCause(
int telephonyDisconnectCause, int telephonyPreciseDisconnectCause, String reason,
int phoneId, ImsReasonInfo imsReasonInfo, PersistableBundle carrierConfig,
- FlagsAdapter featureFlags) {
+ FlagsAdapter featureFlags, boolean shouldTreatAsEmergency) {
Context context = PhoneGlobals.getInstance();
return new DisconnectCause.Builder()
@@ -124,7 +147,7 @@
.setLabel(toTelecomDisconnectCauseLabel(context, telephonyDisconnectCause,
telephonyPreciseDisconnectCause, carrierConfig, featureFlags))
.setDescription(toTelecomDisconnectCauseDescription(
- context, telephonyDisconnectCause, phoneId))
+ context, telephonyDisconnectCause, phoneId, shouldTreatAsEmergency))
.setReason(toTelecomDisconnectReason(
context, telephonyDisconnectCause, reason, phoneId))
.setTone(toTelecomDisconnectCauseTone(
@@ -633,7 +656,8 @@
* Returns a description of the disconnect cause to be shown to the user.
*/
private static CharSequence toTelecomDisconnectCauseDescription(
- Context context, int telephonyDisconnectCause, int phoneId) {
+ Context context, int telephonyDisconnectCause, int phoneId,
+ boolean shouldTreatAsEmergency) {
if (context == null ) {
return "";
}
@@ -756,14 +780,31 @@
case android.telephony.DisconnectCause.OUT_OF_SERVICE:
// No network connection.
+ FeatureFlags mFeatureFlags = new FeatureFlagsImpl();
if (ImsUtil.shouldPromoteWfc(context, phoneId)) {
resourceId = R.string.incall_error_promote_wfc;
} else if (ImsUtil.isWfcModeWifiOnly(context, phoneId)) {
resourceId = R.string.incall_error_wfc_only_no_wireless_network;
} else if (ImsUtil.isWfcEnabled(context, phoneId)) {
- resourceId = R.string.incall_error_out_of_service_wfc;
+ if (!mFeatureFlags.showCallFailNotificationFor2gToggle()) {
+ resourceId = R.string.incall_error_out_of_service_wfc;
+ break;
+ }
+ if (is2gDisabled(phoneId) && !shouldTreatAsEmergency) {
+ resourceId = R.string.incall_error_out_of_service_wfc_2g_user;
+ } else {
+ resourceId = R.string.incall_error_out_of_service_wfc;
+ }
} else {
- resourceId = R.string.incall_error_out_of_service;
+ if (!mFeatureFlags.showCallFailNotificationFor2gToggle()) {
+ resourceId = R.string.incall_error_out_of_service;
+ break;
+ }
+ if (is2gDisabled(phoneId) && !shouldTreatAsEmergency) {
+ resourceId = R.string.incall_error_out_of_service_2g;
+ } else {
+ resourceId = R.string.incall_error_out_of_service;
+ }
}
break;
@@ -986,4 +1027,18 @@
return config;
}
+ /**
+ * Returns true if 2G is disabled.
+ */
+ protected static boolean is2gDisabled(int phoneId) {
+ Phone phone = PhoneFactory.getPhone(phoneId);
+ if (phone == null) {
+ return false;
+ }
+ long bitmask2g = TelephonyManager.NETWORK_CLASS_BITMASK_2G;
+ long currentlyAllowedNetworkTypes = phone.getAllowedNetworkTypes(
+ TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G);
+ boolean is2gEnabled = (currentlyAllowedNetworkTypes & bitmask2g) != 0;
+ return !is2gEnabled;
+ }
}
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 7749a2c..5bfad6b 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -2561,7 +2561,8 @@
preciseDisconnectCause,
mOriginalConnection.getVendorDisconnectCause(),
getPhone().getPhoneId(), imsReasonInfo,
- new FlagsAdapterImpl()));
+ new FlagsAdapterImpl(),
+ shouldTreatAsEmergencyCall()));
close();
}
break;
diff --git a/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java b/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java
index e5f7fd3..71a23e6 100644
--- a/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java
+++ b/tests/src/com/android/services/telephony/DisconnectCauseUtilTest.java
@@ -152,7 +152,8 @@
android.telecom.DisconnectCause tcCause =
DisconnectCauseUtil.toTelecomDisconnectCause(
DisconnectCause.BUSY, -1 /* precise label is NOT given */,
- EMPTY_STRING, PHONE_ID, null, getBundleWithBusyToneArray(), mFeatureFlags);
+ EMPTY_STRING, PHONE_ID, null, getBundleWithBusyToneArray(), mFeatureFlags,
+ false);
assertBusyCauseWithTargetLabel(R.string.callFailed_userBusy, tcCause);
}
@@ -170,7 +171,8 @@
android.telecom.DisconnectCause tcCause =
DisconnectCauseUtil.toTelecomDisconnectCause(DisconnectCause.BUSY,
CallFailCause.USER_BUSY /* Telephony defined a precise label */,
- EMPTY_STRING, PHONE_ID, null, getBundleWithBusyToneArray(), mFeatureFlags);
+ EMPTY_STRING, PHONE_ID, null, getBundleWithBusyToneArray(), mFeatureFlags,
+ false);
// Note: The precise label should not be overridden even though the carrier defined
// the cause to play a busy tone
assertBusyCauseWithTargetLabel(R.string.clh_callFailed_user_busy_txt, tcCause);