Loading src/java/com/android/internal/telephony/Connection.java +12 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ public abstract class Connection { public void onVideoProviderChanged( android.telecom.Connection.VideoProvider videoProvider); public void onAudioQualityChanged(int audioQuality); public void onMediaAttributesChanged(); public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants); public void onCallSubstateChanged(int callSubstate); public void onMultipartyStateChanged(boolean isMultiParty); Loading Loading @@ -151,6 +152,8 @@ public abstract class Connection { @Override public void onAudioQualityChanged(int audioQuality) {} @Override public void onMediaAttributesChanged() {} @Override public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants) {} @Override public void onCallSubstateChanged(int callSubstate) {} Loading Loading @@ -1100,6 +1103,15 @@ public abstract class Connection { } } /** * Notifies interested parties of changes to the media attributes of the call. */ public void notifyMediaAttributesChanged() { for (Listener l: mListeners) { l.onMediaAttributesChanged(); } } /** * Notifies listeners that connection extras has changed. * @param extras New connection extras. This Bundle will be cloned to ensure that any concurrent Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java +12 −0 Original line number Diff line number Diff line Loading @@ -1079,6 +1079,8 @@ public class ImsPhoneConnection extends Connection implements } } boolean mediaAttributesChanged = false; // Metrics for audio codec if (localCallProfile != null && localCallProfile.mMediaProfile.mAudioQuality != mAudioCodec) { Loading @@ -1086,6 +1088,7 @@ public class ImsPhoneConnection extends Connection implements mMetrics.writeAudioCodecIms(mOwner.mPhone.getPhoneId(), imsCall.getCallSession()); mOwner.getPhone().getVoiceCallSessionStats().onAudioCodecChanged(this, mAudioCodec); changed = true; mediaAttributesChanged = true; } if (localCallProfile != null Loading @@ -1097,13 +1100,22 @@ public class ImsPhoneConnection extends Connection implements - audioCodecAttributes.getBitrateRangeKbps().getUpper()) > THRESHOLD) { mAudioCodecBitrateKbps = audioCodecAttributes.getBitrateRangeKbps().getUpper(); changed = true; mediaAttributesChanged = true; } if (Math.abs(mAudioCodecBandwidthKhz - audioCodecAttributes.getBandwidthRangeKhz().getUpper()) > THRESHOLD) { mAudioCodecBandwidthKhz = audioCodecAttributes.getBandwidthRangeKhz().getUpper(); changed = true; mediaAttributesChanged = true; } } if (mediaAttributesChanged) { Rlog.i(LOG_TAG, "updateMediaCapabilities: mediate attributes changed: codec = " + mAudioCodec + ", bitRate=" + mAudioCodecBitrateKbps + ", bandwidth=" + mAudioCodecBandwidthKhz); notifyMediaAttributesChanged(); } int newAudioQuality = Loading tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java +49 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.internal.telephony.imsphone; import static android.telephony.ims.ImsStreamMediaProfile.AUDIO_QUALITY_AMR_WB; import static android.telephony.ims.ImsStreamMediaProfile.AUDIO_QUALITY_EVS_SWB; import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; import static org.junit.Assert.assertEquals; Loading @@ -27,8 +30,10 @@ import static org.mockito.Mockito.anyChar; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.os.AsyncResult; import android.os.Bundle; Loading @@ -40,16 +45,20 @@ import android.telephony.PhoneNumberUtils; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.telephony.ims.ImsCallProfile; import android.telephony.ims.ImsStreamMediaProfile; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import com.android.ims.ImsCall; import com.android.ims.ImsException; import com.android.internal.telephony.Call; import com.android.internal.telephony.Connection; import com.android.internal.telephony.GsmCdmaCall; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.metrics.VoiceCallSessionStats; import org.junit.After; import org.junit.Assert; Loading @@ -62,10 +71,14 @@ import org.mockito.stubbing.Answer; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class ImsPhoneConnectionTest extends TelephonyTest { private static final int TIMEOUT_MILLIS = 5000; private ImsPhoneConnection mConnectionUT; private Bundle mBundle = new Bundle(); @Mock Loading Loading @@ -429,4 +442,40 @@ public class ImsPhoneConnectionTest extends TelephonyTest { assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE)); assertEquals(forwardedNumber, mConnectionUT.getForwardedNumber()); } @Test @SmallTest public void testReportMediaCodecChange() throws InterruptedException, ImsException { ImsCall imsCall = mock(ImsCall.class); ImsStreamMediaProfile mediaProfile = new ImsStreamMediaProfile(); ImsCallProfile profile = new ImsCallProfile(); profile.mMediaProfile = mediaProfile; mediaProfile.mAudioQuality = AUDIO_QUALITY_AMR_WB; when(imsCall.getLocalCallProfile()).thenReturn(profile); // Blech; mocks required which are unrelated to this test when(mImsCT.getPhone()).thenReturn(mImsPhone); VoiceCallSessionStats stats = mock(VoiceCallSessionStats.class); when(mImsPhone.getVoiceCallSessionStats()).thenReturn(stats); mConnectionUT = new ImsPhoneConnection(mImsPhone, imsCall, mImsCT, mForeGroundCall, false); CountDownLatch latch = new CountDownLatch(1); boolean[] receivedCountCallback = new boolean[1]; mConnectionUT.addListener(new Connection.ListenerBase() { @Override public void onMediaAttributesChanged() { receivedCountCallback[0] = true; latch.countDown(); } }); mConnectionUT.updateMediaCapabilities(imsCall); // Make an update to the media caps mediaProfile.mAudioQuality = AUDIO_QUALITY_EVS_SWB; mConnectionUT.updateMediaCapabilities(imsCall); latch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); assertTrue(receivedCountCallback[0]); } } Loading
src/java/com/android/internal/telephony/Connection.java +12 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ public abstract class Connection { public void onVideoProviderChanged( android.telecom.Connection.VideoProvider videoProvider); public void onAudioQualityChanged(int audioQuality); public void onMediaAttributesChanged(); public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants); public void onCallSubstateChanged(int callSubstate); public void onMultipartyStateChanged(boolean isMultiParty); Loading Loading @@ -151,6 +152,8 @@ public abstract class Connection { @Override public void onAudioQualityChanged(int audioQuality) {} @Override public void onMediaAttributesChanged() {} @Override public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants) {} @Override public void onCallSubstateChanged(int callSubstate) {} Loading Loading @@ -1100,6 +1103,15 @@ public abstract class Connection { } } /** * Notifies interested parties of changes to the media attributes of the call. */ public void notifyMediaAttributesChanged() { for (Listener l: mListeners) { l.onMediaAttributesChanged(); } } /** * Notifies listeners that connection extras has changed. * @param extras New connection extras. This Bundle will be cloned to ensure that any concurrent Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java +12 −0 Original line number Diff line number Diff line Loading @@ -1079,6 +1079,8 @@ public class ImsPhoneConnection extends Connection implements } } boolean mediaAttributesChanged = false; // Metrics for audio codec if (localCallProfile != null && localCallProfile.mMediaProfile.mAudioQuality != mAudioCodec) { Loading @@ -1086,6 +1088,7 @@ public class ImsPhoneConnection extends Connection implements mMetrics.writeAudioCodecIms(mOwner.mPhone.getPhoneId(), imsCall.getCallSession()); mOwner.getPhone().getVoiceCallSessionStats().onAudioCodecChanged(this, mAudioCodec); changed = true; mediaAttributesChanged = true; } if (localCallProfile != null Loading @@ -1097,13 +1100,22 @@ public class ImsPhoneConnection extends Connection implements - audioCodecAttributes.getBitrateRangeKbps().getUpper()) > THRESHOLD) { mAudioCodecBitrateKbps = audioCodecAttributes.getBitrateRangeKbps().getUpper(); changed = true; mediaAttributesChanged = true; } if (Math.abs(mAudioCodecBandwidthKhz - audioCodecAttributes.getBandwidthRangeKhz().getUpper()) > THRESHOLD) { mAudioCodecBandwidthKhz = audioCodecAttributes.getBandwidthRangeKhz().getUpper(); changed = true; mediaAttributesChanged = true; } } if (mediaAttributesChanged) { Rlog.i(LOG_TAG, "updateMediaCapabilities: mediate attributes changed: codec = " + mAudioCodec + ", bitRate=" + mAudioCodecBitrateKbps + ", bandwidth=" + mAudioCodecBandwidthKhz); notifyMediaAttributesChanged(); } int newAudioQuality = Loading
tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java +49 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.internal.telephony.imsphone; import static android.telephony.ims.ImsStreamMediaProfile.AUDIO_QUALITY_AMR_WB; import static android.telephony.ims.ImsStreamMediaProfile.AUDIO_QUALITY_EVS_SWB; import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; import static org.junit.Assert.assertEquals; Loading @@ -27,8 +30,10 @@ import static org.mockito.Mockito.anyChar; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.os.AsyncResult; import android.os.Bundle; Loading @@ -40,16 +45,20 @@ import android.telephony.PhoneNumberUtils; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.telephony.ims.ImsCallProfile; import android.telephony.ims.ImsStreamMediaProfile; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import com.android.ims.ImsCall; import com.android.ims.ImsException; import com.android.internal.telephony.Call; import com.android.internal.telephony.Connection; import com.android.internal.telephony.GsmCdmaCall; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.metrics.VoiceCallSessionStats; import org.junit.After; import org.junit.Assert; Loading @@ -62,10 +71,14 @@ import org.mockito.stubbing.Answer; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class ImsPhoneConnectionTest extends TelephonyTest { private static final int TIMEOUT_MILLIS = 5000; private ImsPhoneConnection mConnectionUT; private Bundle mBundle = new Bundle(); @Mock Loading Loading @@ -429,4 +442,40 @@ public class ImsPhoneConnectionTest extends TelephonyTest { assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE)); assertEquals(forwardedNumber, mConnectionUT.getForwardedNumber()); } @Test @SmallTest public void testReportMediaCodecChange() throws InterruptedException, ImsException { ImsCall imsCall = mock(ImsCall.class); ImsStreamMediaProfile mediaProfile = new ImsStreamMediaProfile(); ImsCallProfile profile = new ImsCallProfile(); profile.mMediaProfile = mediaProfile; mediaProfile.mAudioQuality = AUDIO_QUALITY_AMR_WB; when(imsCall.getLocalCallProfile()).thenReturn(profile); // Blech; mocks required which are unrelated to this test when(mImsCT.getPhone()).thenReturn(mImsPhone); VoiceCallSessionStats stats = mock(VoiceCallSessionStats.class); when(mImsPhone.getVoiceCallSessionStats()).thenReturn(stats); mConnectionUT = new ImsPhoneConnection(mImsPhone, imsCall, mImsCT, mForeGroundCall, false); CountDownLatch latch = new CountDownLatch(1); boolean[] receivedCountCallback = new boolean[1]; mConnectionUT.addListener(new Connection.ListenerBase() { @Override public void onMediaAttributesChanged() { receivedCountCallback[0] = true; latch.countDown(); } }); mConnectionUT.updateMediaCapabilities(imsCall); // Make an update to the media caps mediaProfile.mAudioQuality = AUDIO_QUALITY_EVS_SWB; mConnectionUT.updateMediaCapabilities(imsCall); latch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); assertTrue(receivedCountCallback[0]); } }