Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 276bc503 authored by Tyler Gunn's avatar Tyler Gunn
Browse files

Cannot swap active and background calls after failing to merge.

When a conference call merge fails, an attempt to swap between the active
and held calls will fail; resuming the bg call fails.  The problem is
switchWaitingOrHoldingAndActive swaps the FG/BG ImsCall references before
getting positive confirmation that they suceeded.

1. When initiating a call swap, keep track of the call we expect to
resume.  In the resume success method, check if we resume a call other than
the one we expect to.  In the resume fail method, check if we failed to
resume the call we expected to.  In both cases, switch the FG/BG call
references back to ensure that state signaling is handled properly.
2. Trigger a notifySuppServiceFailed on the phone to report that the
resume failed; this is used by Telephony to display a failure message.

Bug: 18656014
Change-Id: I8e67389601861a933c648ca876d4e8a12ef54fee
parent 9dd8bcd9
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -66,7 +66,7 @@ public interface Phone {
    }
    }


    enum SuppService {
    enum SuppService {
      UNKNOWN, SWITCH, SEPARATE, TRANSFER, CONFERENCE, REJECT, HANGUP;
      UNKNOWN, SWITCH, SEPARATE, TRANSFER, CONFERENCE, REJECT, HANGUP, RESUME;
    }
    }


    // "Features" accessible through the connectivity manager
    // "Features" accessible through the connectivity manager
+27 −0
Original line number Original line Diff line number Diff line
@@ -176,6 +176,8 @@ public final class ImsPhoneCallTracker extends CallTracker {
    private int pendingCallClirMode;
    private int pendingCallClirMode;
    private int pendingCallVideoState;
    private int pendingCallVideoState;
    private boolean pendingCallInEcm = false;
    private boolean pendingCallInEcm = false;
    private boolean mSwitchingFgAndBgCalls = false;
    private ImsCall mCallExpectedToResume = null;


    //***** Events
    //***** Events


@@ -490,8 +492,14 @@ public final class ImsPhoneCallTracker extends CallTracker {
                throw new CallStateException("no ims call");
                throw new CallStateException("no ims call");
            }
            }


            // Swap the ImsCalls pointed to by the foreground and background ImsPhoneCalls.
            // If hold or resume later fails, we will swap them back.
            mSwitchingFgAndBgCalls = true;
            mCallExpectedToResume = mBackgroundCall.getImsCall();
            mForegroundCall.switchWith(mBackgroundCall);
            mForegroundCall.switchWith(mBackgroundCall);


            // Hold the foreground call; once the foreground call is held, the background call will
            // be resumed.
            try {
            try {
                imsCall.hold();
                imsCall.hold();
            } catch (ImsException e) {
            } catch (ImsException e) {
@@ -1003,6 +1011,9 @@ public final class ImsPhoneCallTracker extends CallTracker {
                processCallStateChange(imsCall, ImsPhoneCall.State.HOLDING,
                processCallStateChange(imsCall, ImsPhoneCall.State.HOLDING,
                        DisconnectCause.NOT_DISCONNECTED);
                        DisconnectCause.NOT_DISCONNECTED);
                if (oldState == ImsPhoneCall.State.ACTIVE) {
                if (oldState == ImsPhoneCall.State.ACTIVE) {
                    // Note: This case comes up when we have just held a call in response to a
                    // switchWaitingOrHoldingAndActive.  We now need to resume the background call.
                    // The EVENT_RESUME_BACKGROUND causes resumeWaitingOrHolding to be called.
                    if ((mForegroundCall.getState() == ImsPhoneCall.State.HOLDING)
                    if ((mForegroundCall.getState() == ImsPhoneCall.State.HOLDING)
                            || (mRingingCall.getState() == ImsPhoneCall.State.WAITING)) {
                            || (mRingingCall.getState() == ImsPhoneCall.State.WAITING)) {


@@ -1045,6 +1056,14 @@ public final class ImsPhoneCallTracker extends CallTracker {
        public void onCallResumed(ImsCall imsCall) {
        public void onCallResumed(ImsCall imsCall) {
            if (DBG) log("onCallResumed");
            if (DBG) log("onCallResumed");


            // If we are the in midst of swapping FG and BG calls and the call we end up resuming
            // is not the one we expected, we likely had a resume failure and we need to swap the
            // FG and BG calls back.
            if (mSwitchingFgAndBgCalls && imsCall != mCallExpectedToResume) {
                mForegroundCall.switchWith(mBackgroundCall);
                mSwitchingFgAndBgCalls = false;
                mCallExpectedToResume = null;
            }
            processCallStateChange(imsCall, ImsPhoneCall.State.ACTIVE,
            processCallStateChange(imsCall, ImsPhoneCall.State.ACTIVE,
                    DisconnectCause.NOT_DISCONNECTED);
                    DisconnectCause.NOT_DISCONNECTED);
        }
        }
@@ -1052,6 +1071,14 @@ public final class ImsPhoneCallTracker extends CallTracker {
        @Override
        @Override
        public void onCallResumeFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
        public void onCallResumeFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
            // TODO : What should be done?
            // TODO : What should be done?
            // If we are in the midst of swapping the FG and BG calls and we got a resume fail, we
            // need to swap back the FG and BG calls.
            if (mSwitchingFgAndBgCalls && imsCall == mCallExpectedToResume) {
                mForegroundCall.switchWith(mBackgroundCall);
                mCallExpectedToResume = null;
                mSwitchingFgAndBgCalls = false;
            }
            mPhone.notifySuppServiceFailed(Phone.SuppService.RESUME);
        }
        }


        @Override
        @Override