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

Commit 632f4e1a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Handle ringback changes between call state changes." into sc-dev

parents cb89a45f 65ec57cd
Loading
Loading
Loading
Loading
+43 −17
Original line number Diff line number Diff line
@@ -334,44 +334,70 @@ public class ImsPhoneCall extends Call {
        }

        ImsStreamMediaProfile mediaProfile = imsCall.getCallProfile().mMediaProfile;

        return (mediaProfile.mAudioDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE)
        boolean shouldPlayRingback =
                (mediaProfile.mAudioDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE)
                        ? true : false;
        Rlog.i(LOG_TAG, "isLocalTone: audioDirection=" + mediaProfile.mAudioDirection
                + ", playRingback=" + shouldPlayRingback);
        return shouldPlayRingback;
    }

    public boolean update(ImsPhoneConnection conn, ImsCall imsCall, State state) {
        boolean changed = false;
        State oldState = mState;

        // We will try to start or stop ringback whenever the call has major call state changes.
        maybeChangeRingbackState(imsCall, state);

        if ((state != mState) && (state != State.DISCONNECTED)) {
            mState = state;
            changed = true;
        } else if (state == State.DISCONNECTED) {
            changed = true;
        }

        if (VDBG) {
            Rlog.v(LOG_TAG, "update : " + mCallContext + " state: " + oldState + " --> " + mState);
        }

        return changed;
    }

    /**
     * Determines whether to change the ringback state for a call.
     * @param imsCall The call.
     */
    public void maybeChangeRingbackState(ImsCall imsCall) {
        maybeChangeRingbackState(imsCall, mState);
    }

    /**
     * Determines whether local ringback should be playing for the call.  We will play local
     * ringback when a call is in an ALERTING state and the audio direction is DIRECTION_INACTIVE.
     * @param imsCall The call the change pertains to.
     * @param state The current state of the call.
     */
    private void maybeChangeRingbackState(ImsCall imsCall, State state) {
        //ImsCall.Listener.onCallProgressing can be invoked several times
        //and ringback tone mode can be changed during the call setup procedure
        Rlog.i(LOG_TAG, "maybeChangeRingbackState: state=" + state);
        if (state == State.ALERTING) {
            if (mIsRingbackTonePlaying && !isLocalTone(imsCall)) {
                Rlog.i(LOG_TAG, "maybeChangeRingbackState: stop ringback");
                getPhone().stopRingbackTone();
                mIsRingbackTonePlaying = false;
            } else if (!mIsRingbackTonePlaying && isLocalTone(imsCall)) {
                Rlog.i(LOG_TAG, "maybeChangeRingbackState: start ringback");
                getPhone().startRingbackTone();
                mIsRingbackTonePlaying = true;
            }
        } else {
            if (mIsRingbackTonePlaying) {
                Rlog.i(LOG_TAG, "maybeChangeRingbackState: stop ringback");
                getPhone().stopRingbackTone();
                mIsRingbackTonePlaying = false;
            }
        }

        if ((state != mState) && (state != State.DISCONNECTED)) {
            mState = state;
            changed = true;
        } else if (state == State.DISCONNECTED) {
            changed = true;
        }

        if (VDBG) {
            Rlog.v(LOG_TAG, "update : " + mCallContext + " state: " + oldState + " --> " + mState);
        }

        return changed;
    }

    /* package */ ImsPhoneConnection
+3 −0
Original line number Diff line number Diff line
@@ -2579,6 +2579,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
        if (ignoreState) {
            conn.updateAddressDisplay(imsCall);
            conn.updateExtras(imsCall);
            // Some devices will change the audio direction between major call state changes, so we
            // need to check whether to start or stop ringback
            conn.maybeChangeRingbackState();

            maybeSetVideoCallProvider(conn, imsCall);
            return;
+8 −0
Original line number Diff line number Diff line
@@ -854,6 +854,14 @@ public class ImsPhoneConnection extends Connection implements
        return updateParent || updateAddressDisplay || updateMediaCapabilities || updateExtras;
    }

    /**
     * Re-evaluate whether ringback should be playing.
     */
    public void maybeChangeRingbackState() {
        Rlog.i(LOG_TAG, "maybeChangeRingbackState");
        mParent.maybeChangeRingbackState(mImsCall);
    }

    @Override
    public int getPreciseDisconnectCause() {
        return mPreciseDisconnectCause;
+58 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -139,6 +140,63 @@ public class ImsPhoneCallTest extends TelephonyTest {
        assertEquals(Call.State.ACTIVE, mImsCallUT.getState());
    }

    /**
     * Verifies we can handle starting ringback between call state changes.
     */
    @Test
    @SmallTest
    public void testUpdateRingBackToneBetweenStateChange() {
        mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE;
        mImsCallProfile.mMediaProfile = mMediaProfile;

        // This call state change should NOT start ringback since it the direction is wrong.
        mImsCallUT.update(null, mImsCall, Call.State.ALERTING);
        verify(mImsPhone, never()).startRingbackTone();
        assertEquals(Call.State.ALERTING, mImsCallUT.getState());

        // Simulate a change to the profile without a state change.
        mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_INACTIVE;
        mImsCallUT.maybeChangeRingbackState(mImsCall);
        verify(mImsPhone, times(1)).startRingbackTone();

        // And then assume the call goes active, which would stop the ringback.
        mImsCallUT.update(null, mImsCall, Call.State.ACTIVE);
        verify(mImsPhone, times(1)).stopRingbackTone();
        assertEquals(Call.State.ACTIVE, mImsCallUT.getState());
    }

    /**
     * Verifies we can handle ringback start/stop entirely between call state changes.
     */
    @Test
    @SmallTest
    public void testUpdateRingBackToneBetweenStateChangeTwo() {
        mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE;
        mImsCallProfile.mMediaProfile = mMediaProfile;

        // This call state change should NOT start ringback since it the direction is wrong.
        mImsCallUT.update(null, mImsCall, Call.State.ALERTING);
        verify(mImsPhone, never()).startRingbackTone();
        assertEquals(Call.State.ALERTING, mImsCallUT.getState());

        // Simulate a change to the profile without a state change.
        mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_INACTIVE;
        mImsCallUT.maybeChangeRingbackState(mImsCall);
        verify(mImsPhone, times(1)).startRingbackTone();

        // Simulate another change to the profile without a state change.
        mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE;
        mImsCallUT.maybeChangeRingbackState(mImsCall);
        verify(mImsPhone, times(1)).stopRingbackTone();

        // And then assume the call goes active, which should not impact ringback state.
        mImsCallUT.update(null, mImsCall, Call.State.ACTIVE);
        assertEquals(Call.State.ACTIVE, mImsCallUT.getState());
        // Should still have only started and stopped once
        verify(mImsPhone, times(1)).startRingbackTone();
        verify(mImsPhone, times(1)).stopRingbackTone();
    }

    @Test
    @SmallTest
    public void testStopRingingOnHandover() {