diff options
author | Venkata Manikumar Punyamanthula <quic_c_vpunya@quicinc.com> | 2022-04-26 00:44:36 +0530 |
---|---|---|
committer | Venkata Manikumar Punyamanthula <quic_c_vpunya@quicinc.com> | 2022-04-26 00:44:36 +0530 |
commit | f3661c4ba2033408a805aefaa74cdcc3167af6bd (patch) | |
tree | 5a1b6e2d927302ccee31a42549f415d3db320c51 | |
parent | 5c994a5ac595695140113ff729384106b8e29b48 (diff) |
IMS: Answer incoming call after disconnect dialing call completes
- In the dsda mode, there is dialing call on one sub and incoming
call on the other sub. When answering incoming call, the first
answer always fails. This is because the outgoing call was not
disconnected completely.
- Moved disconnect call to AnswerAndReleaseHandler and answer incoming
call after disconnect dialing call completes.
Change-Id: I0902808366f13a85febfc40da9ed90eebd8d9193
CRs-Fixed: 3128365
-rw-r--r-- | src/com/android/services/telephony/AnswerAndReleaseHandler.java | 38 | ||||
-rw-r--r-- | src/com/android/services/telephony/TelephonyConnectionService.java | 29 |
2 files changed, 56 insertions, 11 deletions
diff --git a/src/com/android/services/telephony/AnswerAndReleaseHandler.java b/src/com/android/services/telephony/AnswerAndReleaseHandler.java index f3e74985a6..ebdaeb664e 100644 --- a/src/com/android/services/telephony/AnswerAndReleaseHandler.java +++ b/src/com/android/services/telephony/AnswerAndReleaseHandler.java @@ -37,11 +37,17 @@ import android.telecom.VideoProfile; import com.android.ims.internal.ConferenceParticipant; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +/** + * This class is used to support Pseudo DSDA in telephony that will handle BT / headset + * scenarios and DSDA mode for handling Dialing + incoming scenarios. + * + */ public class AnswerAndReleaseHandler extends TelephonyConnection.TelephonyConnectionListener { private List<Connection> mConnectionList = new CopyOnWriteArrayList<>(); @@ -49,10 +55,26 @@ public class AnswerAndReleaseHandler extends TelephonyConnection.TelephonyConnec private int mVideoState; private Connection mIncomingConnection = null; private List<Listener> mListeners = new CopyOnWriteArrayList<>(); + private List<Integer> mPermittedConnectionStates = new CopyOnWriteArrayList<>(); + private List<Integer> mPermittedConfConnectionStates = new CopyOnWriteArrayList<>(); - public AnswerAndReleaseHandler(Connection incomingConnection, int answerWithVideoState) { + public AnswerAndReleaseHandler(Connection incomingConnection, int answerWithVideoState, + boolean dsdaMode) { mVideoState = answerWithVideoState; mIncomingConnection = incomingConnection; + // Initialize an array of connection states that wants to exempt from disconnecting + // and use/check it in checkAndAnswer(). + mPermittedConnectionStates.add(Connection.STATE_RINGING); + mPermittedConnectionStates.add(Connection.STATE_DISCONNECTED); + mPermittedConfConnectionStates.add(Connection.STATE_DISCONNECTED); + if (dsdaMode) { + mPermittedConnectionStates.add(Connection.STATE_ACTIVE); + mPermittedConnectionStates.add(Connection.STATE_HOLDING); + mPermittedConnectionStates.add(Connection.STATE_PULLING_CALL); + mPermittedConfConnectionStates.add(Connection.STATE_HOLDING); + mPermittedConfConnectionStates.add(Connection.STATE_ACTIVE); + mPermittedConfConnectionStates.add(Connection.STATE_PULLING_CALL); + } } public interface Listener { @@ -101,10 +123,10 @@ public class AnswerAndReleaseHandler extends TelephonyConnection.TelephonyConnec if (!(current instanceof TelephonyConnection)) { continue; } - int state = current.getState(); - if (state == Connection.STATE_RINGING || - state == Connection.STATE_DISCONNECTED) { - continue; + synchronized(mPermittedConnectionStates) { + if (mPermittedConnectionStates.contains(current.getState())) { + continue; + } } boolean containsConnection = false; synchronized(mConnectionList) { @@ -121,8 +143,10 @@ public class AnswerAndReleaseHandler extends TelephonyConnection.TelephonyConnec if (!(current instanceof TelephonyConferenceBase)) { continue; } - if (current.getState() == Connection.STATE_DISCONNECTED) { - continue; + synchronized(mPermittedConfConnectionStates) { + if (mPermittedConfConnectionStates.contains(current.getState())) { + continue; + } } boolean containsConference = false; synchronized(mConferenceList) { diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java index 9655b7e052..a2beb7ddea 100644 --- a/src/com/android/services/telephony/TelephonyConnectionService.java +++ b/src/com/android/services/telephony/TelephonyConnectionService.java @@ -766,7 +766,7 @@ public class TelephonyConnectionService extends ConnectionService { return; } // Pseudo DSDA use case - setupAnswerAndReleaseHandler(answerAndReleaseConnection, videoState); + setupAnswerAndReleaseHandler(answerAndReleaseConnection, videoState, false); } private Connection shallDisconnectOtherCalls() { @@ -3143,6 +3143,21 @@ public class TelephonyConnectionService extends ConnectionService { } /** + * Checks to see if there is dialing call present on a sub other than the one passed in. + * @param incomingHandle The new incoming connection {@link PhoneAccountHandle} + */ + private boolean isDialingCallPresentOnOtherSub(@NonNull PhoneAccountHandle incomingHandle) { + return getAllConnections().stream() + .filter(c -> + // Exclude multiendpoint calls as they're not on this device. + (c.getConnectionProperties() & Connection.PROPERTY_IS_EXTERNAL_CALL) == 0 + && c.getState() == Connection.STATE_DIALING + // Include any calls not on same sub as current connection. + && !Objects.equals(c.getPhoneAccountHandle(), incomingHandle)) + .count() > 0; + } + + /** * Checks to see if there are calls present on a sub other than the one passed in. * @param incomingHandle The new incoming connection {@link PhoneAccountHandle} */ @@ -3245,7 +3260,12 @@ public class TelephonyConnectionService extends ConnectionService { connToAnswer.getExtras().getBoolean( Connection.EXTRA_ANSWERING_DROPS_FG_CALL, false)) { // Pseudo DSDA use case - setupAnswerAndReleaseHandler(connToAnswer, videoState); + setupAnswerAndReleaseHandler(connToAnswer, videoState, false); + return; + } + //DSDA mode, dialing call + incoming call, accept incoming call and release dialing call + if (isDialingCallPresentOnOtherSub(connToAnswer.getPhoneAccountHandle())) { + setupAnswerAndReleaseHandler(connToAnswer, videoState, true); return; } // Get connection to hold if any @@ -3271,9 +3291,10 @@ public class TelephonyConnectionService extends ConnectionService { } } - private void setupAnswerAndReleaseHandler(Connection conn, int videoState) { + private void setupAnswerAndReleaseHandler(Connection conn, int videoState, + boolean dsdaMode) { mAnswerAndReleaseHandler = - new AnswerAndReleaseHandler(conn, videoState); + new AnswerAndReleaseHandler(conn, videoState, dsdaMode); mAnswerAndReleaseHandler.addListener(mAnswerAndReleaseListener); mAnswerAndReleaseHandler.checkAndAnswer(getAllConnections(), getAllConferences()); |