IMS: No option to merge calls in VoWIFI
- Making changes in ImsUtils to check the WFC
capabilities per slot.
Test: Manual
Bug: 74177709
Change-Id: I97941afb4d05fd7ced0b67e54c1032260f4a0987
diff --git a/src/com/android/phone/ImsUtil.java b/src/com/android/phone/ImsUtil.java
index 4d8ff80..d83d869 100644
--- a/src/com/android/phone/ImsUtil.java
+++ b/src/com/android/phone/ImsUtil.java
@@ -53,11 +53,20 @@
* @return {@code true} if WFC is supported by the platform and has been enabled by the user.
*/
public static boolean isWfcEnabled(Context context) {
- ImsManager imsManager = getDefaultImsManagerInstance(context);
+ return isWfcEnabled(context, SubscriptionManager.getDefaultVoicePhoneId());
+ }
+
+ /**
+ * @return {@code true} if WFC is supported per Slot and has been enabled by the user.
+ */
+ public static boolean isWfcEnabled(Context context, int phoneId) {
+ ImsManager imsManager = ImsManager.getInstance(context, phoneId);
boolean isEnabledByPlatform = imsManager.isWfcEnabledByPlatform();
boolean isEnabledByUser = imsManager.isWfcEnabledByUser();
- if (DBG) Log.d(LOG_TAG, "isWfcEnabled :: isEnabledByPlatform=" + isEnabledByPlatform);
- if (DBG) Log.d(LOG_TAG, "isWfcEnabled :: isEnabledByUser=" + isEnabledByUser);
+ if (DBG) Log.d(LOG_TAG, "isWfcEnabled :: isEnabledByPlatform=" + isEnabledByPlatform
+ + " phoneId=" + phoneId);
+ if (DBG) Log.d(LOG_TAG, "isWfcEnabled :: isEnabledByUser=" + isEnabledByUser
+ + " phoneId=" + phoneId);
return isEnabledByPlatform && isEnabledByUser;
}
@@ -66,10 +75,20 @@
* enabled, this will return {@code false}.
*/
public static boolean isWfcModeWifiOnly(Context context) {
- boolean isWifiOnlyMode = getDefaultImsManagerInstance(context).getWfcMode()
- == ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
- if (DBG) Log.d(LOG_TAG, "isWfcModeWifiOnly :: isWifiOnlyMode" + isWifiOnlyMode);
- return isWfcEnabled(context) && isWifiOnlyMode;
+ return isWfcModeWifiOnly(context, SubscriptionManager.getDefaultVoicePhoneId());
+ }
+
+ /**
+ * @return {@code true} if the Slot is configured to use "Wi-Fi only" mode. If WFC is not
+ * enabled, this will return {@code false}.
+ */
+ public static boolean isWfcModeWifiOnly(Context context, int phoneId) {
+ ImsManager imsManager = ImsManager.getInstance(context, phoneId);
+ boolean isWifiOnlyMode =
+ imsManager.getWfcMode() == ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
+ if (DBG) Log.d(LOG_TAG, "isWfcModeWifiOnly :: isWifiOnlyMode" + isWifiOnlyMode
+ + " phoneId=" + phoneId);
+ return isWfcEnabled(context, phoneId) && isWifiOnlyMode;
}
/**
@@ -81,9 +100,21 @@
* @return {@code true} if use of WFC should be promoted, {@code false} otherwise.
*/
public static boolean shouldPromoteWfc(Context context) {
+ return shouldPromoteWfc(context, SubscriptionManager.getDefaultVoicePhoneId());
+ }
+
+ /**
+ * When a call cannot be placed, determines if the use of WFC should be promoted, per the
+ * carrier config of the slot. Use of WFC is promoted to the user if the device is
+ * connected to a WIFI network, WFC is disabled but provisioned, and the carrier config
+ * indicates that the features should be promoted.
+ *
+ * @return {@code true} if use of WFC should be promoted, {@code false} otherwise.
+ */
+ public static boolean shouldPromoteWfc(Context context, int phoneId) {
CarrierConfigManager cfgManager = (CarrierConfigManager) context
.getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (cfgManager == null || !cfgManager.getConfig()
+ if (cfgManager == null || cfgManager.getConfigForSubId(getSubId(phoneId))
.getBoolean(CarrierConfigManager.KEY_CARRIER_PROMOTE_WFC_ON_CALL_FAIL_BOOL)) {
return false;
}
@@ -97,7 +128,8 @@
if (cm != null) {
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni != null && ni.isConnected()) {
- return ni.getType() == ConnectivityManager.TYPE_WIFI && !isWfcEnabled(context);
+ return ni.getType() == ConnectivityManager.TYPE_WIFI && !isWfcEnabled(context,
+ phoneId);
}
}
return false;
@@ -106,4 +138,13 @@
private static ImsManager getDefaultImsManagerInstance(Context context) {
return ImsManager.getInstance(context, SubscriptionManager.getDefaultVoicePhoneId());
}
+
+ private static int getSubId(int phoneId) {
+ final int[] subIds = SubscriptionManager.getSubId(phoneId);
+ int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ if (subIds != null && subIds.length >= 1) {
+ subId = subIds[0];
+ }
+ return subId;
+ }
}
diff --git a/src/com/android/services/telephony/CdmaConnection.java b/src/com/android/services/telephony/CdmaConnection.java
index ffa9dbc..4c869a9 100644
--- a/src/com/android/services/telephony/CdmaConnection.java
+++ b/src/com/android/services/telephony/CdmaConnection.java
@@ -224,7 +224,8 @@
} catch (CallStateException e) {
Log.e(this, e, "Failed to hangup call waiting call");
}
- setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(telephonyDisconnectCause));
+ setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(telephonyDisconnectCause,
+ null, getPhone().getPhoneId()));
}
}
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index 361e5dc..d6d63d3 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.media.ToneGenerator;
import android.telecom.DisconnectCause;
+import android.telephony.SubscriptionManager;
import com.android.internal.telephony.CallFailCause;
import com.android.phone.ImsUtil;
@@ -63,13 +64,44 @@
*/
public static DisconnectCause toTelecomDisconnectCause(
int telephonyDisconnectCause, int telephonyPerciseDisconnectCause, String reason) {
+ return toTelecomDisconnectCause(telephonyDisconnectCause, telephonyPerciseDisconnectCause,
+ reason, SubscriptionManager.getDefaultVoicePhoneId());
+ }
+
+ /**
+ * 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 phoneId To support localized message based on phoneId
+ */
+ public static DisconnectCause toTelecomDisconnectCause(int telephonyDisconnectCause,
+ String reason, int phoneId) {
+ return toTelecomDisconnectCause(telephonyDisconnectCause, CallFailCause.NOT_VALID,
+ reason, phoneId);
+ }
+
+ /**
+ * 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 telephonyPerciseDisconnectCause The code for the percise 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
+ */
+ public static DisconnectCause toTelecomDisconnectCause(
+ int telephonyDisconnectCause, int telephonyPerciseDisconnectCause, String reason,
+ int phoneId) {
Context context = PhoneGlobals.getInstance();
return new DisconnectCause(
toTelecomDisconnectCauseCode(telephonyDisconnectCause),
toTelecomDisconnectCauseLabel(context, telephonyDisconnectCause,
telephonyPerciseDisconnectCause),
- toTelecomDisconnectCauseDescription(context, telephonyDisconnectCause),
- toTelecomDisconnectReason(context,telephonyDisconnectCause, reason),
+ toTelecomDisconnectCauseDescription(context, telephonyDisconnectCause, phoneId),
+ toTelecomDisconnectReason(context,telephonyDisconnectCause, reason, phoneId),
toTelecomDisconnectCauseTone(telephonyDisconnectCause));
}
@@ -483,7 +515,7 @@
* Returns a description of the disconnect cause to be shown to the user.
*/
private static CharSequence toTelecomDisconnectCauseDescription(
- Context context, int telephonyDisconnectCause) {
+ Context context, int telephonyDisconnectCause, int phoneId) {
if (context == null ) {
return "";
}
@@ -560,11 +592,11 @@
// TODO: Offer the option to turn the radio on, and automatically retry the call
// once network registration is complete.
- if (ImsUtil.shouldPromoteWfc(context)) {
+ if (ImsUtil.shouldPromoteWfc(context, phoneId)) {
resourceId = R.string.incall_error_promote_wfc;
- } else if (ImsUtil.isWfcModeWifiOnly(context)) {
+ } else if (ImsUtil.isWfcModeWifiOnly(context, phoneId)) {
resourceId = R.string.incall_error_wfc_only_no_wireless_network;
- } else if (ImsUtil.isWfcEnabled(context)) {
+ } else if (ImsUtil.isWfcEnabled(context, phoneId)) {
resourceId = R.string.incall_error_power_off_wfc;
} else {
resourceId = R.string.incall_error_power_off;
@@ -592,11 +624,11 @@
case android.telephony.DisconnectCause.OUT_OF_SERVICE:
// No network connection.
- if (ImsUtil.shouldPromoteWfc(context)) {
+ if (ImsUtil.shouldPromoteWfc(context, phoneId)) {
resourceId = R.string.incall_error_promote_wfc;
- } else if (ImsUtil.isWfcModeWifiOnly(context)) {
+ } else if (ImsUtil.isWfcModeWifiOnly(context, phoneId)) {
resourceId = R.string.incall_error_wfc_only_no_wireless_network;
- } else if (ImsUtil.isWfcEnabled(context)) {
+ } else if (ImsUtil.isWfcEnabled(context, phoneId)) {
resourceId = R.string.incall_error_out_of_service_wfc;
} else {
resourceId = R.string.incall_error_out_of_service;
@@ -670,7 +702,7 @@
* @return The disconnect reason.
*/
private static String toTelecomDisconnectReason(Context context, int telephonyDisconnectCause,
- String reason) {
+ String reason, int phoneId) {
if (context == null) {
return "";
@@ -682,7 +714,7 @@
// intentional fall-through
case android.telephony.DisconnectCause.OUT_OF_SERVICE:
// No network connection.
- if (ImsUtil.shouldPromoteWfc(context)) {
+ if (ImsUtil.shouldPromoteWfc(context, phoneId)) {
return android.telecom.DisconnectCause.REASON_WIFI_ON_BUT_WFC_OFF;
}
break;
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 830027c..ba55cf4 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -935,8 +935,14 @@
if (mConferenceHost == null) {
disconnectCause = new DisconnectCause(DisconnectCause.CANCELED);
} else {
- disconnectCause = DisconnectCauseUtil.toTelecomDisconnectCause(
- mConferenceHost.getOriginalConnection().getDisconnectCause());
+ if (mConferenceHost.getPhone() != null) {
+ disconnectCause = DisconnectCauseUtil.toTelecomDisconnectCause(
+ mConferenceHost.getOriginalConnection().getDisconnectCause(),
+ null, mConferenceHost.getPhone().getPhoneId());
+ } else {
+ disconnectCause = DisconnectCauseUtil.toTelecomDisconnectCause(
+ mConferenceHost.getOriginalConnection().getDisconnectCause());
+ }
}
setDisconnected(disconnectCause);
disconnectConferenceParticipants();
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index b81eeab..56a9fca 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -1189,7 +1189,7 @@
wasVideoCall = call.wasVideoCall();
}
- isVowifiEnabled = ImsUtil.isWfcEnabled(phone.getContext());
+ isVowifiEnabled = ImsUtil.isWfcEnabled(phone.getContext(), phone.getPhoneId());
}
if (isCurrentVideoCall) {
@@ -1566,7 +1566,8 @@
setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
mOriginalConnection.getDisconnectCause(),
preciseDisconnectCause,
- mOriginalConnection.getVendorDisconnectCause()));
+ mOriginalConnection.getVendorDisconnectCause(),
+ getPhone().getPhoneId()));
close();
}
break;
@@ -2074,7 +2075,7 @@
boolean isVoWifiEnabled = false;
if (isIms) {
ImsPhone imsPhone = (ImsPhone) phone;
- isVoWifiEnabled = ImsUtil.isWfcEnabled(phone.getContext());
+ isVoWifiEnabled = ImsUtil.isWfcEnabled(phone.getContext(), phone.getPhoneId());
}
PhoneAccountHandle phoneAccountHandle = isIms ? PhoneUtils
.makePstnPhoneAccountHandle(phone.getDefaultPhone())
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index c7b2096..d937d96 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -290,7 +290,8 @@
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
android.telephony.DisconnectCause.VOICEMAIL_NUMBER_MISSING,
- "Voicemail scheme provided but no voicemail number set."));
+ "Voicemail scheme provided but no voicemail number set.",
+ phone.getPhoneId()));
}
// Convert voicemail: to tel:
@@ -331,7 +332,8 @@
DisconnectCauseUtil.toTelecomDisconnectCause(
android.telephony.DisconnectCause
.CDMA_ALREADY_ACTIVATED,
- "Tried to dial *228"));
+ "Tried to dial *228",
+ phone.getPhoneId()));
}
}
}
@@ -481,7 +483,8 @@
originalConnection.setDisconnected(
DisconnectCauseUtil.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUTGOING_CANCELED,
- "Reconnecting outgoing Emergency Call."));
+ "Reconnecting outgoing Emergency Call.",
+ phone.getPhoneId()));
originalConnection.destroy();
} else {
placeOutgoingConnection((TelephonyConnection) originalConnection, phone, request);
@@ -579,8 +582,8 @@
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
android.telephony.DisconnectCause.CDMA_NOT_EMERGENCY,
- "Cannot make non-emergency call in ECM mode."
- ));
+ "Cannot make non-emergency call in ECM mode.",
+ phone.getPhoneId()));
}
}
@@ -597,7 +600,8 @@
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUT_OF_SERVICE,
- "ServiceState.STATE_OUT_OF_SERVICE"));
+ "ServiceState.STATE_OUT_OF_SERVICE",
+ phone.getPhoneId()));
}
case ServiceState.STATE_POWER_OFF:
// Don't disconnect if radio is power off because the device is on Bluetooth.
@@ -607,13 +611,15 @@
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
android.telephony.DisconnectCause.POWER_OFF,
- "ServiceState.STATE_POWER_OFF"));
+ "ServiceState.STATE_POWER_OFF",
+ phone.getPhoneId()));
default:
Log.d(this, "onCreateOutgoingConnection, unknown service state: %d", state);
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUTGOING_FAILURE,
- "Unknown service state " + state));
+ "Unknown service state " + state,
+ phone.getPhoneId()));
}
}
@@ -621,7 +627,8 @@
if (VideoProfile.isVideo(request.getVideoState()) && isTtyModeEnabled(context) &&
!isEmergencyNumber) {
return Connection.createFailedConnection(DisconnectCauseUtil.toTelecomDisconnectCause(
- android.telephony.DisconnectCause.VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED));
+ android.telephony.DisconnectCause.VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED,
+ null, phone.getPhoneId()));
}
// Check for additional limits on CDMA phones.
@@ -635,7 +642,8 @@
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
android.telephony.DisconnectCause.DIALED_CALL_FORWARDING_WHILE_ROAMING,
- "Call forwarding while roaming"));
+ "Call forwarding while roaming",
+ phone.getPhoneId()));
}
@@ -646,7 +654,8 @@
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
android.telephony.DisconnectCause.OUTGOING_FAILURE,
- "Invalid phone type"));
+ "Invalid phone type",
+ phone.getPhoneId()));
}
connection.setAddress(handle, PhoneConstants.PRESENTATION_ALLOWED);
connection.setInitializing();
@@ -685,7 +694,8 @@
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
android.telephony.DisconnectCause.INCOMING_MISSED,
- "Found no ringing call"));
+ "Found no ringing call",
+ phone.getPhoneId()));
}
com.android.internal.telephony.Connection originalConnection =
@@ -1036,7 +1046,7 @@
cause = android.telephony.DisconnectCause.POWER_OFF;
}
connection.setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
- cause, e.getMessage()));
+ cause, e.getMessage(), phone.getPhoneId()));
connection.clearOriginalConnection();
connection.destroy();
return;
@@ -1060,7 +1070,7 @@
}
Log.d(this, "placeOutgoingConnection, phone.dial returned null");
connection.setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
- telephonyDisconnectCause, "Connection is null"));
+ telephonyDisconnectCause, "Connection is null", phone.getPhoneId()));
connection.clearOriginalConnection();
connection.destroy();
} else {