Loading flags/telecom_call_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,14 @@ flag { bug: "390116261" } # OWNER=pmadapurmath TARGET=25Q4 flag { name: "revert_disconnecting_during_merge" namespace: "telecom" description: "When a user tries hanging up a call during a call merge, the hangup will be ignore but the call will be stuck in disconnecting. We prevent the call state from being placed into disconnecting." bug: "409455144" } # OWNER=tjstuart TARGET=25Q3 flag { name: "cleanup_verify_call_state" Loading res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -438,6 +438,9 @@ <!-- In-call screen: error message shown when the user attempts to dial an MMI code, but there is an ongoing call on a different phone account. --> <string name="callFailed_reject_mmi">This MMI code is not available for calls across multiple accounts.</string> <!-- In-call screen: error message shown when the user attempts to hang up a call during a call merge. --> <string name="call_hangup_fail_during_merge">Call cannot be disconnected during a merge.</string> <!-- In-call screen: error message shown when the user attempts to dial an MMI code during an ongoing emergency call. --> <string name="emergencyCall_reject_mmi">MMI codes cannot be dialed during an emergency call.</string> Loading src/com/android/server/telecom/Call.java +1 −1 Original line number Diff line number Diff line Loading @@ -4388,7 +4388,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, * * @param isLocallyDisconnecting {@code true} if this call is locally disconnecting. */ private void setLocallyDisconnecting(boolean isLocallyDisconnecting) { public void setLocallyDisconnecting(boolean isLocallyDisconnecting) { mIsLocallyDisconnecting = isLocallyDisconnecting; } Loading src/com/android/server/telecom/InCallController.java +23 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import android.os.UserManager; import android.permission.PermissionManager; import android.telecom.CallAudioState; import android.telecom.CallEndpoint; import android.telecom.Connection; import android.telecom.ConnectionService; import android.telecom.InCallService; import android.telecom.Log; Loading Loading @@ -1985,6 +1986,11 @@ public class InCallController extends CallsManagerListenerBase implements UserHandle userFromCall = getUserFromCall(call); Map<UserHandle, Map<InCallController.InCallServiceInfo, IInCallService>> serviceMap = getCombinedInCallServiceMap(); // In the case that we receive a disconnect failed event, ensure that the call state is // reverted if it's in disconnecting and ensure we send the update to the ICS as well. if (Connection.EVENT_DISCONNECT_FAILED.equals(event)) { handleCallDisconnectFailed(call); } if (serviceMap.containsKey(userFromCall)) { for (IInCallService inCallService : serviceMap.get(userFromCall).values()) { try { Loading @@ -1999,6 +2005,23 @@ public class InCallController extends CallsManagerListenerBase implements } } /** * When we receive a disconnect failure connection event, the old call state will be in * disconnecting given that the locally disconnecting state is set. Notify the ICS with the new * call state to ensure they get the new update if they had been notified that the call was * disconnecting. * @param call The call that received the disconnect failure event. */ private void handleCallDisconnectFailed(Call call) { Log.i(this, "handleCallDisconnectFailed: call: %s", call); call.setLocallyDisconnecting(false); updateCall(call); // Show an error dialog to the user mentioning why the disconnect failed. UserUtil.showErrorDialogForRestrictedOutgoingCall(mContext, R.string.call_hangup_fail_during_merge, NOTIFICATION_TAG, "Call cannot be disconnected during a call merge."); } private void notifyRttInitiationFailure(Call call, int reason) { UserHandle userFromCall = getUserFromCall(call); Map<UserHandle, Map<InCallController.InCallServiceInfo, IInCallService>> serviceMap = Loading src/com/android/server/telecom/callsequencing/VerifyCallStateChangeTransaction.java +13 −0 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import com.android.server.telecom.CallState; import com.android.server.telecom.TelecomSystem; import com.android.server.telecom.flags.FeatureFlags; import android.os.Bundle; import android.telecom.CallException; import android.telecom.Connection; import android.telecom.Log; import java.util.Set; Loading Loading @@ -101,6 +103,17 @@ public class VerifyCallStateChangeTransaction extends CallTransaction { CallException.CODE_CALL_CANNOT_BE_SET_TO_ACTIVE, "error unholding call")); } } @Override public void onConnectionEvent(Call call, String event, Bundle extras) { // If one of the target states is disconnected and we receive a disconnect failed event // from Telephony, we can safely fail the transaction. if (call.equals(mCall) && Connection.EVENT_DISCONNECT_FAILED.equals(event) && mTargetCallStates.contains(CallState.DISCONNECTED)) { mTransactionResult.complete(new CallTransactionResult( CallException.CODE_ERROR_UNKNOWN, "error disconnecting call")); } } }; public VerifyCallStateChangeTransaction(TelecomSystem.SyncRoot lock, Call call, Loading Loading
flags/telecom_call_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,14 @@ flag { bug: "390116261" } # OWNER=pmadapurmath TARGET=25Q4 flag { name: "revert_disconnecting_during_merge" namespace: "telecom" description: "When a user tries hanging up a call during a call merge, the hangup will be ignore but the call will be stuck in disconnecting. We prevent the call state from being placed into disconnecting." bug: "409455144" } # OWNER=tjstuart TARGET=25Q3 flag { name: "cleanup_verify_call_state" Loading
res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -438,6 +438,9 @@ <!-- In-call screen: error message shown when the user attempts to dial an MMI code, but there is an ongoing call on a different phone account. --> <string name="callFailed_reject_mmi">This MMI code is not available for calls across multiple accounts.</string> <!-- In-call screen: error message shown when the user attempts to hang up a call during a call merge. --> <string name="call_hangup_fail_during_merge">Call cannot be disconnected during a merge.</string> <!-- In-call screen: error message shown when the user attempts to dial an MMI code during an ongoing emergency call. --> <string name="emergencyCall_reject_mmi">MMI codes cannot be dialed during an emergency call.</string> Loading
src/com/android/server/telecom/Call.java +1 −1 Original line number Diff line number Diff line Loading @@ -4388,7 +4388,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, * * @param isLocallyDisconnecting {@code true} if this call is locally disconnecting. */ private void setLocallyDisconnecting(boolean isLocallyDisconnecting) { public void setLocallyDisconnecting(boolean isLocallyDisconnecting) { mIsLocallyDisconnecting = isLocallyDisconnecting; } Loading
src/com/android/server/telecom/InCallController.java +23 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import android.os.UserManager; import android.permission.PermissionManager; import android.telecom.CallAudioState; import android.telecom.CallEndpoint; import android.telecom.Connection; import android.telecom.ConnectionService; import android.telecom.InCallService; import android.telecom.Log; Loading Loading @@ -1985,6 +1986,11 @@ public class InCallController extends CallsManagerListenerBase implements UserHandle userFromCall = getUserFromCall(call); Map<UserHandle, Map<InCallController.InCallServiceInfo, IInCallService>> serviceMap = getCombinedInCallServiceMap(); // In the case that we receive a disconnect failed event, ensure that the call state is // reverted if it's in disconnecting and ensure we send the update to the ICS as well. if (Connection.EVENT_DISCONNECT_FAILED.equals(event)) { handleCallDisconnectFailed(call); } if (serviceMap.containsKey(userFromCall)) { for (IInCallService inCallService : serviceMap.get(userFromCall).values()) { try { Loading @@ -1999,6 +2005,23 @@ public class InCallController extends CallsManagerListenerBase implements } } /** * When we receive a disconnect failure connection event, the old call state will be in * disconnecting given that the locally disconnecting state is set. Notify the ICS with the new * call state to ensure they get the new update if they had been notified that the call was * disconnecting. * @param call The call that received the disconnect failure event. */ private void handleCallDisconnectFailed(Call call) { Log.i(this, "handleCallDisconnectFailed: call: %s", call); call.setLocallyDisconnecting(false); updateCall(call); // Show an error dialog to the user mentioning why the disconnect failed. UserUtil.showErrorDialogForRestrictedOutgoingCall(mContext, R.string.call_hangup_fail_during_merge, NOTIFICATION_TAG, "Call cannot be disconnected during a call merge."); } private void notifyRttInitiationFailure(Call call, int reason) { UserHandle userFromCall = getUserFromCall(call); Map<UserHandle, Map<InCallController.InCallServiceInfo, IInCallService>> serviceMap = Loading
src/com/android/server/telecom/callsequencing/VerifyCallStateChangeTransaction.java +13 −0 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import com.android.server.telecom.CallState; import com.android.server.telecom.TelecomSystem; import com.android.server.telecom.flags.FeatureFlags; import android.os.Bundle; import android.telecom.CallException; import android.telecom.Connection; import android.telecom.Log; import java.util.Set; Loading Loading @@ -101,6 +103,17 @@ public class VerifyCallStateChangeTransaction extends CallTransaction { CallException.CODE_CALL_CANNOT_BE_SET_TO_ACTIVE, "error unholding call")); } } @Override public void onConnectionEvent(Call call, String event, Bundle extras) { // If one of the target states is disconnected and we receive a disconnect failed event // from Telephony, we can safely fail the transaction. if (call.equals(mCall) && Connection.EVENT_DISCONNECT_FAILED.equals(event) && mTargetCallStates.contains(CallState.DISCONNECTED)) { mTransactionResult.complete(new CallTransactionResult( CallException.CODE_ERROR_UNKNOWN, "error disconnecting call")); } } }; public VerifyCallStateChangeTransaction(TelecomSystem.SyncRoot lock, Call call, Loading