Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java +43 −17 Original line number Diff line number Diff line Loading @@ -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 Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java +58 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java +43 −17 Original line number Diff line number Diff line Loading @@ -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 Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java +58 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading