diff options
author | Jayachandran C <jayachandranc@google.com> | 2022-03-08 01:58:38 -0800 |
---|---|---|
committer | Jayachandran C <jayachandranc@google.com> | 2022-03-17 22:51:55 -0700 |
commit | 5f4e38c54614c4bec667fe608b3d2282e7a44a70 (patch) | |
tree | e9d7d917946d5c0e5e998da310b836aeff53e480 /tests/unit | |
parent | 1a8e7192868bba65528dfdacb5c15a9cdb45e2da (diff) | |
download | ImsMedia-5f4e38c54614c4bec667fe608b3d2282e7a44a70.tar.gz |
Add changes to AudioOffloadService to connect to HAL and invoke APIs
Bug: 203240638
Test: atest
Change-Id: I9cba55293fba9829c2efcbc6a4ccaa7efb3bff66
Diffstat (limited to 'tests/unit')
6 files changed, 563 insertions, 48 deletions
diff --git a/tests/unit/AndroidManifest.xml b/tests/unit/AndroidManifest.xml index 6c500bef..1e547795 100644 --- a/tests/unit/AndroidManifest.xml +++ b/tests/unit/AndroidManifest.xml @@ -15,6 +15,8 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.telephony.imsmedia.tests"> + <uses-permission android:name="android.permission.INTERNET"/> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application> <uses-library android:name="android.test.runner" /> </application> diff --git a/tests/unit/src/com/android/telephony/imsmedia/AmrParamsTest.java b/tests/unit/src/com/android/telephony/imsmedia/AmrParamsTest.java index 14c6c41c..d5fd5fc6 100644 --- a/tests/unit/src/com/android/telephony/imsmedia/AmrParamsTest.java +++ b/tests/unit/src/com/android/telephony/imsmedia/AmrParamsTest.java @@ -30,9 +30,18 @@ public class AmrParamsTest { private static final boolean OCTET_ALIGNED = true; private static final int MAX_REDUNDANCY_MILLIS = 1001; + private AmrParams createAmrParams(int amrMode, + boolean octetAligned, int maxRedundancyMillis) { + return new AmrParams.Builder() + .setAmrMode(amrMode) + .setOctetAligned(octetAligned) + .setMaxRedundancyMillis(maxRedundancyMillis) + .build(); + } + @Test public void testConstructorAndGetters() { - AmrParams amr = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, + AmrParams amr = createAmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, MAX_REDUNDANCY_MILLIS); assertThat(amr.getAmrMode()).isEqualTo(AmrParams.AMR_MODE_5); @@ -42,7 +51,7 @@ public class AmrParamsTest { @Test public void testParcel() { - AmrParams amr = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, MAX_REDUNDANCY_MILLIS); + AmrParams amr = createAmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, MAX_REDUNDANCY_MILLIS); Parcel parcel = Parcel.obtain(); amr.writeToParcel(parcel, 0); @@ -54,10 +63,10 @@ public class AmrParamsTest { @Test public void testEqual() { - AmrParams amr1 = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, + AmrParams amr1 = createAmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, MAX_REDUNDANCY_MILLIS); - AmrParams amr2 = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, + AmrParams amr2 = createAmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, MAX_REDUNDANCY_MILLIS); assertThat(amr1).isEqualTo(amr2); @@ -65,19 +74,19 @@ public class AmrParamsTest { @Test public void testNotEqual() { - AmrParams amr1 = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, + AmrParams amr1 = createAmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, MAX_REDUNDANCY_MILLIS); - AmrParams amr2 = new AmrParams(AmrParams.AMR_MODE_6, OCTET_ALIGNED, + AmrParams amr2 = createAmrParams(AmrParams.AMR_MODE_6, OCTET_ALIGNED, MAX_REDUNDANCY_MILLIS); assertThat(amr1).isNotEqualTo(amr2); - AmrParams amr3 = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, 1002); + AmrParams amr3 = createAmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, 1002); assertThat(amr1).isNotEqualTo(amr3); - AmrParams amr4 = new AmrParams(AmrParams.AMR_MODE_5, false, MAX_REDUNDANCY_MILLIS); + AmrParams amr4 = createAmrParams(AmrParams.AMR_MODE_5, false, MAX_REDUNDANCY_MILLIS); assertThat(amr1).isNotEqualTo(amr4); } diff --git a/tests/unit/src/com/android/telephony/imsmedia/AudioConfigTest.java b/tests/unit/src/com/android/telephony/imsmedia/AudioConfigTest.java index 024abf1e..fbd8b012 100644 --- a/tests/unit/src/com/android/telephony/imsmedia/AudioConfigTest.java +++ b/tests/unit/src/com/android/telephony/imsmedia/AudioConfigTest.java @@ -53,16 +53,16 @@ public class AudioConfigTest { private static final String REMOTE_RTP_ADDRESS = "122.22.22.22"; private static final int REMOTE_RTP_PORT = 2222; private static final int MAX_MTU_BYTES = 1524; - private static final int DSCP = 1999; - private static final int RX_PAYLOAD = 2001; - private static final int TX_PAYLOAD = 2002; + private static final byte DSCP = 10; + private static final byte RX_PAYLOAD = 112; + private static final byte TX_PAYLOAD = 122; private static final byte SAMPLING_RATE = 98; private static final byte PTIME = 99; - private static final byte MAX_PTIME = 100; + private static final int MAX_PTIME = 240; private static final byte CMR = 100; private static final boolean DTX_ENABLED = true; - private static final int DTMF_PAYLOAD = 1001; - private static final int DTMF_SAMPLING_RATE = 1002; + private static final byte DTMF_PAYLOAD = 126; + private static final byte DTMF_SAMPLING_RATE = 127; private static final RtcpConfig rtcp = new RtcpConfig.Builder() .setCanonicalName(CANONICAL_NAME) @@ -71,12 +71,20 @@ public class AudioConfigTest { .setRtcpXrBlockTypes(RtcpConfig.FLAG_RTCPXR_DLRR_REPORT_BLOCK) .build(); - private static final EvsParams evs = new EvsParams(EvsParams.EVS_SUPER_WIDE_BAND, - EvsParams.EVS_MODE_7, CHANNEL_AWARE_MODE, - USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); + private static final EvsParams evs = new EvsParams.Builder() + .setEvsbandwidth(EvsParams.EVS_SUPER_WIDE_BAND) + .setEvsMode(EvsParams.EVS_MODE_7) + .setChannelAwareMode(CHANNEL_AWARE_MODE) + .setHeaderFullOnlyOnTx(USE_HEADER_FULL_ONLY_TX) + .setHeaderFullOnlyOnRx(USE_HEADER_FULL_ONLY_RX) + .build(); + + private static final AmrParams amr = new AmrParams.Builder() + .setAmrMode(AmrParams.AMR_MODE_5) + .setOctetAligned(OCTET_ALIGNED) + .setMaxRedundancyMillis(MAX_REDUNDANCY_MILLIS) + .build(); - private static final AmrParams amr = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, - MAX_REDUNDANCY_MILLIS); @Test public void testConstructorAndGetters() { AudioConfig config = createAudioConfig(); @@ -89,14 +97,14 @@ public class AudioConfigTest { assertThat(config.getDtxEnabled()).isEqualTo(DTX_ENABLED); assertThat(config.getCodecType()).isEqualTo(AudioConfig.CODEC_EVS); assertThat(config.getDtmfPayloadTypeNumber()).isEqualTo(DTMF_PAYLOAD); - assertThat(config.getDtmfsamplingRateKHz()).isEqualTo(DTMF_SAMPLING_RATE); + assertThat(config.getDtmfSamplingRateKHz()).isEqualTo(DTMF_SAMPLING_RATE); assertThat(config.getAmrParams()).isEqualTo(null); assertThat(config.getEvsParams()).isEqualTo(evs); assertThat(config.getAccessNetwork()).isEqualTo(AccessNetworkType.EUTRAN); assertThat(config.getRemoteRtpAddress()).isEqualTo(new InetSocketAddress( InetAddresses.parseNumericAddress(REMOTE_RTP_ADDRESS), REMOTE_RTP_PORT)); assertThat(config.getRtcpConfig()).isEqualTo(rtcp); - assertThat(config.getmaxMtuBytes()).isEqualTo(MAX_MTU_BYTES); + assertThat(config.getMaxMtuBytes()).isEqualTo(MAX_MTU_BYTES); assertThat(config.getRxPayloadTypeNumber()).isEqualTo(RX_PAYLOAD); assertThat(config.getTxPayloadTypeNumber()).isEqualTo(TX_PAYLOAD); assertThat(config.getSamplingRateKHz()).isEqualTo(SAMPLING_RATE); @@ -145,7 +153,7 @@ public class AudioConfigTest { .setDtxEnabled(DTX_ENABLED) .setCodecType(AudioConfig.CODEC_EVS) .setDtmfPayloadTypeNumber(DTMF_PAYLOAD) - .setDtmfsamplingRateKHz(DTMF_SAMPLING_RATE) + .setDtmfSamplingRateKHz(DTMF_SAMPLING_RATE) .setAmrParams(amr) .setEvsParams(evs) .build(); @@ -171,7 +179,7 @@ public class AudioConfigTest { .setDtxEnabled(DTX_ENABLED) .setCodecType(AudioConfig.CODEC_EVS) .setDtmfPayloadTypeNumber(DTMF_PAYLOAD) - .setDtmfsamplingRateKHz(DTMF_SAMPLING_RATE) + .setDtmfSamplingRateKHz(DTMF_SAMPLING_RATE) .setEvsParams(evs) .build(); } diff --git a/tests/unit/src/com/android/telephony/imsmedia/AudioOffloadTest.java b/tests/unit/src/com/android/telephony/imsmedia/AudioOffloadTest.java new file mode 100644 index 00000000..bc076efd --- /dev/null +++ b/tests/unit/src/com/android/telephony/imsmedia/AudioOffloadTest.java @@ -0,0 +1,463 @@ +/** + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.telephony.imsmedia; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static junit.framework.Assert.assertEquals; + +import android.hardware.radio.ims.media.IImsMedia; +import android.hardware.radio.ims.media.IImsMediaSession; +import android.hardware.radio.ims.media.MediaProtocolType; +import android.hardware.radio.ims.media.RtpConfig; +import android.hardware.radio.ims.media.RtpError; +import android.hardware.radio.ims.media.RtpSessionState; +import android.os.Looper; +import android.os.Message; +import android.os.ParcelFileDescriptor; +import android.os.RemoteException; +import android.telephony.imsmedia.AudioConfig; +import android.telephony.imsmedia.IImsAudioSessionCallback; +import android.telephony.imsmedia.ImsMediaSession; +import android.telephony.imsmedia.MediaQualityThreshold; +import android.telephony.ims.RtpHeaderExtension; +import android.testing.TestableLooper; + +import com.android.telephony.imsmedia.AudioSession; +import com.android.telephony.imsmedia.AudioService; +import com.android.telephony.imsmedia.Utils; +import com.android.telephony.imsmedia.Utils.OpenSessionParams; + +import java.net.DatagramSocket; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(JUnit4.class) +public class AudioOffloadTest { + private static final int SESSION_ID = 1; + private static final int DTMF_VOL = 50; + private static final int DTMF_DURATION = 120; + private static final int UNUSED = -1; + private static final int NO_RESOURCES = ImsMediaSession.RESULT_NO_RESOURCES; + private static final int NO_MEMORY = ImsMediaSession.RESULT_NO_MEMORY; + private static final int SUCCESS = ImsMediaSession.RESULT_SUCCESS; + private static final int RTP = ImsMediaSession.PACKET_TYPE_RTP; + private static final int RTCP = ImsMediaSession.PACKET_TYPE_RTCP; + private static final int INACTIVITY_TIMEOUT = 20; + private static final int PACKET_LOSS = 15; + private static final int JITTER = 200; + private static final char DTMF_DIGIT = '7'; + private AudioSession audioSession; + private AudioOffloadListener offloadListener; + private AudioSession.AudioSessionHandler handler; + private TestableLooper looper; + @Mock + private IImsAudioSessionCallback callback; + @Mock + private IImsMedia imsMedia; + @Mock + private IImsMediaSession imsMediaSession; + @Mock + private AudioOffloadService offloadService; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + offloadService = spy(AudioOffloadService.getInstance()); + doReturn(imsMedia).when(offloadService).getIImsMedia(); + audioSession = new AudioSession(SESSION_ID, callback, null, null, offloadService); + handler = audioSession.getAudioSessionHandler(); + audioSession.setAudioOffload(true); + offloadListener = audioSession.getOffloadListener(); + audioSession.onOpenSessionSuccess(imsMediaSession); + try { + looper = new TestableLooper(handler.getLooper()); + } catch (Exception e) { + fail("Unable to create TestableLooper"); + } + } + + @After + public void tearDown() throws Exception { + if (looper != null) { + looper.destroy(); + looper = null; + } + } + + @Test + public void testOpenSession() { + DatagramSocket rtpSocket = null; + DatagramSocket rtcpSocket = null; + + try { + rtpSocket = new DatagramSocket(); + rtcpSocket = new DatagramSocket(); + } catch (SocketException e) { + fail("SocketException:" + e); + } + + OpenSessionParams params = new OpenSessionParams( + ParcelFileDescriptor.fromDatagramSocket(rtpSocket), + ParcelFileDescriptor.fromDatagramSocket(rtcpSocket), + null, null); + audioSession.openSession(params); + processAllMessages(); + + verify(offloadService, times(1)).openSession(eq(SESSION_ID), eq(params)); + try { + verify(imsMedia, times(1)).openSession(eq(SESSION_ID), any(), eq(null)); + } catch(RemoteException e) { + fail("Failed to invoke openSession:" + e); + } + + rtpSocket.close(); + rtcpSocket.close(); + } + + @Test + public void testCloseSession() { + audioSession.closeSession(); + processAllMessages(); + verify(offloadService, times(1)).closeSession(eq(SESSION_ID)); + } + + @Test + public void testGetSessionState() { + assertThat(audioSession.getSessionId()).isEqualTo(SESSION_ID); + assertThat(audioSession.getSessionState()).isEqualTo(ImsMediaSession.SESSION_STATE_CLOSED); + offloadListener.onSessionChanged(RtpSessionState.OPEN); + processAllMessages(); + assertThat(audioSession.getSessionState()).isEqualTo(ImsMediaSession.SESSION_STATE_OPEN); + } + + @Test + public void testModifySession() { + final AudioConfig inputAudioConfig = AudioConfigTest.createAudioConfig(); + RtpConfig outputRtpConfig = null; + + // Modify Session Request + audioSession.modifySession(inputAudioConfig); + processAllMessages(); + try { + ArgumentCaptor<RtpConfig> argumentCaptor = ArgumentCaptor.forClass(RtpConfig.class); + verify(imsMediaSession, times(1)).modifySession(argumentCaptor.capture()); + // Get the HAL RtpConfig + outputRtpConfig = argumentCaptor.getValue(); + // Covert it back to AudioConfig + final AudioConfig outputAudioConfig = Utils.convertToAudioConfig(outputRtpConfig); + // Ensure both are same + assertEquals(inputAudioConfig, outputAudioConfig); + } catch(RemoteException e) { + fail("Failed to invoke modifySession: " + e); + } + + // Modify Session Response - SUCCESS + offloadListener.onModifySessionResponse(outputRtpConfig, RtpError.NONE); + processAllMessages(); + try { + verify(callback, times(1)).onModifySessionResponse(eq(inputAudioConfig), eq(SUCCESS)); + } catch(RemoteException e) { + fail("Failed to notify modifySessionResponse: " + e); + } + + // Modify Session Response - FAILURE + offloadListener.onModifySessionResponse(outputRtpConfig, RtpError.NO_RESOURCES); + processAllMessages(); + try { + verify(callback, times(1)).onModifySessionResponse( + eq(inputAudioConfig), eq(NO_RESOURCES)); + } catch(RemoteException e) { + fail("Failed to notify modifySessionResponse: " + e); + } + } + + @Test + public void testAddConfig() { + final AudioConfig inputAudioConfig = AudioConfigTest.createAudioConfig(); + RtpConfig outputRtpConfig = null; + + // Add Config Request + audioSession.addConfig(inputAudioConfig); + processAllMessages(); + try { + ArgumentCaptor<RtpConfig> argumentCaptor = ArgumentCaptor.forClass(RtpConfig.class); + verify(imsMediaSession, times(1)).addConfig(argumentCaptor.capture()); + // Get the HAL RtpConfig + outputRtpConfig = argumentCaptor.getValue(); + // Covert it back to AudioConfig + final AudioConfig outputAudioConfig = Utils.convertToAudioConfig(outputRtpConfig); + // Ensure both are same + assertEquals(inputAudioConfig, outputAudioConfig); + } catch(RemoteException e) { + fail("Failed to invoke addConfig: " + e); + } + + // Add Config Response - SUCCESS + offloadListener.onAddConfigResponse(outputRtpConfig, RtpError.NONE); + processAllMessages(); + try { + verify(callback, times(1)).onAddConfigResponse(eq(inputAudioConfig), eq(SUCCESS)); + } catch(RemoteException e) { + fail("Failed to notify addConfigResponse: " + e); + } + + // Add Config Response - FAILURE + offloadListener.onAddConfigResponse(outputRtpConfig, RtpError.NO_MEMORY); + processAllMessages(); + try { + verify(callback, times(1)).onAddConfigResponse(eq(inputAudioConfig), eq(NO_MEMORY)); + } catch(RemoteException e) { + fail("Failed to notify addConfigResponse: " + e); + } + } + + @Test + public void testDeleteConfig() { + final AudioConfig inputAudioConfig = AudioConfigTest.createAudioConfig(); + // Delete Config Request + audioSession.deleteConfig(inputAudioConfig); + processAllMessages(); + try { + ArgumentCaptor<RtpConfig> argumentCaptor = ArgumentCaptor.forClass(RtpConfig.class); + verify(imsMediaSession, times(1)).deleteConfig(argumentCaptor.capture()); + // Get the HAL RtpConfig + final RtpConfig outputRtpConfig = argumentCaptor.getValue(); + // Covert it back to AudioConfig + final AudioConfig outputAudioConfig = Utils.convertToAudioConfig(outputRtpConfig); + // Ensure both are same + assertEquals(inputAudioConfig, outputAudioConfig); + } catch(RemoteException e) { + fail("Failed to invoke deleteConfig: " + e); + } + + } + + @Test + public void testConfirmConfig() { + AudioConfig inputAudioConfig = AudioConfigTest.createAudioConfig(); + RtpConfig outputRtpConfig = null; + + // Confirm Config Request + audioSession.confirmConfig(inputAudioConfig); + processAllMessages(); + try { + ArgumentCaptor<RtpConfig> argumentCaptor = ArgumentCaptor.forClass(RtpConfig.class); + verify(imsMediaSession, times(1)).confirmConfig(argumentCaptor.capture()); + // Get the HAL RtpConfig + outputRtpConfig = argumentCaptor.getValue(); + // Covert it back to AudioConfig + final AudioConfig outputAudioConfig = Utils.convertToAudioConfig(outputRtpConfig); + // Ensure both are same + assertEquals(inputAudioConfig, outputAudioConfig); + } catch(RemoteException e) { + fail("Failed to invoke confirmConfig: " + e); + } + + // Confirm Config Response - SUCCESS + offloadListener.onConfirmConfigResponse(outputRtpConfig, RtpError.NONE); + processAllMessages(); + try { + verify(callback, times(1)).onConfirmConfigResponse(eq(inputAudioConfig), eq(SUCCESS)); + } catch(RemoteException e) { + fail("Failed to notify confirmConfigResponse: " + e); + } + + // Confirm Config Response - FAILURE + offloadListener.onConfirmConfigResponse(outputRtpConfig, RtpError.NO_RESOURCES); + processAllMessages(); + try { + verify(callback, times(1)).onConfirmConfigResponse( + eq(inputAudioConfig), eq(NO_RESOURCES)); + } catch(RemoteException e) { + fail("Failed to notify confirmConfigResponse: " + e); + } + } + + @Test + public void testStartDtmf() { + audioSession.startDtmf(DTMF_DIGIT, DTMF_VOL, DTMF_DURATION); + processAllMessages(); + try { + verify(imsMediaSession, times(1)).startDtmf + (eq(DTMF_DIGIT), eq(DTMF_VOL), eq(DTMF_DURATION)); + } catch(RemoteException e) { + fail("Failed to invoke startDtmf: " + e); + } + } + + @Test + public void testStopDtmf() { + audioSession.stopDtmf(); + processAllMessages(); + try { + verify(imsMediaSession, times(1)).stopDtmf(); + } catch(RemoteException e) { + fail("Failed to invoke stopDtmf: " + e); + } + + } + + @Test + public void testSetMediaQualityThreshold() { + // Set Media Quality Threshold + MediaQualityThreshold threshold = MediaQualityThresholdTest.createMediaQualityThreshold(); + audioSession.setMediaQualityThreshold(threshold); + processAllMessages(); + try { + ArgumentCaptor<android.hardware.radio.ims.media.MediaQualityThreshold> argumentCaptor = + ArgumentCaptor.forClass( + android.hardware.radio.ims.media.MediaQualityThreshold.class); + verify(imsMediaSession, times(1)).setMediaQualityThreshold(argumentCaptor.capture()); + // Get the HAL MediaQualityThreshold + final android.hardware.radio.ims.media.MediaQualityThreshold + halThreshold = argumentCaptor.getValue(); + // Covert it back to {@link MediaQualityThreshold} + final MediaQualityThreshold expectedThreshold = + Utils.convertMediaQualityThreshold(halThreshold); + // Ensure both are same + assertEquals(threshold, expectedThreshold); + } catch(RemoteException e) { + fail("Failed to invoke setMediaQualityThreshold: " + e); + } + + } + + @Test + public void testMediaInactivityInd() { + // Receive Inactivity - RTP + offloadListener.notifyMediaInactivity(MediaProtocolType.RTP, INACTIVITY_TIMEOUT); + processAllMessages(); + try { + verify(callback, times(1)).notifyMediaInactivity(eq(RTP), eq(INACTIVITY_TIMEOUT)); + } catch(RemoteException e) { + fail("Failed to notify notifyMediaInactivity: " + e); + } + + // Receive Inactivity - RTCP + offloadListener.notifyMediaInactivity(MediaProtocolType.RTCP, INACTIVITY_TIMEOUT); + processAllMessages(); + try { + verify(callback, times(1)).notifyMediaInactivity(eq(RTCP), eq(INACTIVITY_TIMEOUT)); + } catch(RemoteException e) { + fail("Failed to notify notifyMediaInactivity: " + e); + } + } + + @Test + public void testPacketLossInd() { + // Receive Packet Loss + offloadListener.notifyPacketLoss(PACKET_LOSS); + processAllMessages(); + try { + verify(callback, times(1)).notifyPacketLoss(eq(PACKET_LOSS)); + } catch(RemoteException e) { + fail("Failed to notify notifyPacketLoss: " + e); + } + } + + @Test + public void testJitterInd() { + // Receive Jitter Indication + offloadListener.notifyJitter(JITTER); + processAllMessages(); + try { + verify(callback, times(1)).notifyJitter(eq(JITTER)); + } catch(RemoteException e) { + fail("Failed to notify notifyJitter: " + e); + } + } + + @Test + public void testFirstMediaPacketReceivedInd() { + final AudioConfig outputAudioConfig = AudioConfigTest.createAudioConfig(); + final RtpConfig inputRtpConfig = Utils.convertToRtpConfig(outputAudioConfig); + + // Receive First MediaPacket Received Indication + offloadListener.onFirstMediaPacketReceived(inputRtpConfig); + processAllMessages(); + try { + verify(callback, times(1)).onFirstMediaPacketReceived(eq(outputAudioConfig)); + } catch(RemoteException e) { + fail("Failed to notify onFirstMediaPacketReceived: " + e); + } + } + + @Test + public void testHeaderExtension() { + final byte[] arr1 = {1, 2, 3, 4}; + final byte[] arr2 = {4, 2, 3, 4, 6}; + final ArrayList inputExtensions = new ArrayList<RtpHeaderExtension>(); + inputExtensions.add(new RtpHeaderExtension(7, arr1)); + inputExtensions.add(new RtpHeaderExtension(8, arr2)); + + List<android.hardware.radio.ims.media.RtpHeaderExtension> halExtensions = null; + + // Send RtpHeaderExtension + audioSession.sendHeaderExtension(inputExtensions); + processAllMessages(); + try { + ArgumentCaptor<List<android.hardware.radio.ims.media.RtpHeaderExtension>> + argumentCaptor = ArgumentCaptor.forClass(List.class); + verify(imsMediaSession, times(1)).sendHeaderExtension(argumentCaptor.capture()); + // Get the HAL RtpHeaderExtension list + halExtensions = argumentCaptor.getValue(); + // Covert it back to {@link RtpHeaderExtension} list + final List<RtpHeaderExtension> outputExtensions = + halExtensions.stream().map(Utils::convertRtpHeaderExtension) + .collect(Collectors.toList()); + // Ensure both are same + assertEquals(inputExtensions, outputExtensions); + } catch(RemoteException e) { + fail("Failed to invoke sendHeaderExtension: " + e); + } + + // Receive HAL RtpHeaderExtension + offloadListener.onHeaderExtensionReceived(halExtensions); + processAllMessages(); + try { + verify(callback, times(1)).onHeaderExtensionReceived(eq(inputExtensions)); + } catch(RemoteException e) { + fail("Failed to notify onHeaderExtensionReceived: " + e); + } + } + + private void processAllMessages() { + while (!looper.getLooper().getQueue().isIdle()) { + looper.processAllMessages(); + } + } +} diff --git a/tests/unit/src/com/android/telephony/imsmedia/AudioSessionTest.java b/tests/unit/src/com/android/telephony/imsmedia/AudioSessionTest.java index 174dc29d..65fcabdd 100644 --- a/tests/unit/src/com/android/telephony/imsmedia/AudioSessionTest.java +++ b/tests/unit/src/com/android/telephony/imsmedia/AudioSessionTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.verify; import android.os.Parcel; import android.os.Looper; import android.os.Message; +import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.telephony.imsmedia.AudioConfig; import android.telephony.imsmedia.IImsAudioSessionCallback; @@ -38,6 +39,8 @@ import com.android.telephony.imsmedia.AudioService; import com.android.telephony.imsmedia.Utils; import com.android.telephony.imsmedia.Utils.OpenSessionParams; +import java.net.DatagramSocket; +import java.net.SocketException; import java.util.ArrayList; import org.junit.After; @@ -54,8 +57,8 @@ public class AudioSessionTest { private static final int DTMF_VOL = 50; private static final int DTMF_DURATION = 120; private static final int UNUSED = -1; - private static final int FAILURE = ImsMediaSession.RESULT_FAILURE; private static final int SUCCESS = ImsMediaSession.RESULT_SUCCESS; + private static final int NO_RESOURCES = ImsMediaSession.RESULT_NO_RESOURCES; private static final int RTP = ImsMediaSession.PACKET_TYPE_RTP; private static final int RTCP = ImsMediaSession.PACKET_TYPE_RTCP; private static final int INACTIVITY_TIMEOUT = 20; @@ -76,7 +79,8 @@ public class AudioSessionTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - audioSession = new AudioSession(SESSION_ID, callback, audioService, audioLocalSession); + audioSession = new AudioSession(SESSION_ID, callback, + audioService, audioLocalSession, null); audioListener = audioSession.getAudioListener(); handler = audioSession.getAudioSessionHandler(); try { @@ -107,7 +111,21 @@ public class AudioSessionTest { @Test public void testOpenSession() { - OpenSessionParams params = new OpenSessionParams(); + DatagramSocket rtpSocket = null; + DatagramSocket rtcpSocket = null; + + try { + rtpSocket = new DatagramSocket(); + rtcpSocket = new DatagramSocket(); + } catch (SocketException e) { + fail("SocketException:" + e); + } + + OpenSessionParams params = new OpenSessionParams( + ParcelFileDescriptor.fromDatagramSocket(rtpSocket), + ParcelFileDescriptor.fromDatagramSocket(rtcpSocket), + null, null); + audioSession.openSession(params); processAllMessages(); verify(audioService, times(1)).openSession(eq(SESSION_ID), eq(params)); @@ -138,7 +156,7 @@ public class AudioSessionTest { processAllMessages(); verify(audioLocalSession, times(1)).modifySession(eq(config)); - // Modify Session Response - SUCCESS + // Modify Session Response - Success audioListener.onMessage( createParcel(AudioSession.EVENT_MODIFY_SESSION_RESPONSE, SUCCESS, config)); processAllMessages(); @@ -148,12 +166,12 @@ public class AudioSessionTest { fail("Failed to notify modifySessionResponse: " + e); } - // Modify Session Response - FAILURE + // Modify Session Response - Failure (NO_RESOURCES) audioListener.onMessage( - createParcel(AudioSession.EVENT_MODIFY_SESSION_RESPONSE, FAILURE, config)); + createParcel(AudioSession.EVENT_MODIFY_SESSION_RESPONSE, NO_RESOURCES, config)); processAllMessages(); try { - verify(callback, times(1)).onModifySessionResponse(eq(config), eq(FAILURE)); + verify(callback, times(1)).onModifySessionResponse(eq(config), eq(NO_RESOURCES)); } catch(RemoteException e) { fail("Failed to notify modifySessionResponse: " + e); } @@ -167,7 +185,7 @@ public class AudioSessionTest { processAllMessages(); verify(audioLocalSession, times(1)).addConfig(eq(config)); - // Add Config Response - SUCCESS + // Add Config Response - Success audioListener.onMessage( createParcel(AudioSession.EVENT_ADD_CONFIG_RESPONSE, SUCCESS, config)); processAllMessages(); @@ -177,12 +195,12 @@ public class AudioSessionTest { fail("Failed to notify addConfigResponse: " + e); } - // Add Config Response - FAILURE + // Add Config Response - Failure (NO_RESOURCES) audioListener.onMessage( - createParcel(AudioSession.EVENT_ADD_CONFIG_RESPONSE, FAILURE, config)); + createParcel(AudioSession.EVENT_ADD_CONFIG_RESPONSE, NO_RESOURCES, config)); processAllMessages(); try { - verify(callback, times(1)).onAddConfigResponse(eq(config), eq(FAILURE)); + verify(callback, times(1)).onAddConfigResponse(eq(config), eq(NO_RESOURCES)); } catch(RemoteException e) { fail("Failed to notify addConfigResponse: " + e); } @@ -205,7 +223,7 @@ public class AudioSessionTest { processAllMessages(); verify(audioLocalSession, times(1)).confirmConfig(eq(config)); - // Confirm Config Response - SUCCESS + // Confirm Config Response - Success audioListener.onMessage( createParcel(AudioSession.EVENT_CONFIRM_CONFIG_RESPONSE, SUCCESS, config)); processAllMessages(); @@ -215,12 +233,12 @@ public class AudioSessionTest { fail("Failed to notify confirmConfigResponse: " + e); } - // Confirm Config Response - FAILURE + // Confirm Config Response - Failure (NO_RESOURCES) audioListener.onMessage( - createParcel(AudioSession.EVENT_CONFIRM_CONFIG_RESPONSE, FAILURE, config)); + createParcel(AudioSession.EVENT_CONFIRM_CONFIG_RESPONSE, NO_RESOURCES, config)); processAllMessages(); try { - verify(callback, times(1)).onConfirmConfigResponse(eq(config), eq(FAILURE)); + verify(callback, times(1)).onConfirmConfigResponse(eq(config), eq(NO_RESOURCES)); } catch(RemoteException e) { fail("Failed to notify confirmConfigResponse: " + e); } diff --git a/tests/unit/src/com/android/telephony/imsmedia/EvsParamsTest.java b/tests/unit/src/com/android/telephony/imsmedia/EvsParamsTest.java index d07cd9dd..6f16ee7f 100644 --- a/tests/unit/src/com/android/telephony/imsmedia/EvsParamsTest.java +++ b/tests/unit/src/com/android/telephony/imsmedia/EvsParamsTest.java @@ -31,9 +31,24 @@ public class EvsParamsTest { private static final boolean USE_HEADER_FULL_ONLY_TX = true; private static final boolean USE_HEADER_FULL_ONLY_RX = false; + private EvsParams createEvsParams( + final int evsBandwidth, + final int evsMode, + final byte channelAwareMode, + final boolean useHeaderFullOnlyOnTx, + final boolean useHeaderFullOnlyOnRx) { + return new EvsParams.Builder() + .setEvsbandwidth(evsBandwidth) + .setEvsMode(evsMode) + .setChannelAwareMode(channelAwareMode) + .setHeaderFullOnlyOnTx(useHeaderFullOnlyOnTx) + .setHeaderFullOnlyOnRx(useHeaderFullOnlyOnRx) + .build(); + } + @Test public void testConstructorAndGetters() { - EvsParams evs = new EvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, + EvsParams evs = createEvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, CHANNEL_AWARE_MODE, USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); assertThat(evs.getEvsBandwidth()).isEqualTo(EvsParams.EVS_WIDE_BAND); @@ -45,7 +60,7 @@ public class EvsParamsTest { @Test public void testParcel() { - EvsParams evs = new EvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, + EvsParams evs = createEvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, CHANNEL_AWARE_MODE, USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); Parcel parcel = Parcel.obtain(); @@ -58,10 +73,10 @@ public class EvsParamsTest { @Test public void testEqual() { - EvsParams evs1 = new EvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, + EvsParams evs1 = createEvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, CHANNEL_AWARE_MODE, USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); - EvsParams evs2 = new EvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, + EvsParams evs2 = createEvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, CHANNEL_AWARE_MODE, USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); assertThat(evs1).isEqualTo(evs2); @@ -69,30 +84,30 @@ public class EvsParamsTest { @Test public void testNotEqual() { - EvsParams evs1 = new EvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, + EvsParams evs1 = createEvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, CHANNEL_AWARE_MODE, USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); - EvsParams evs2 = new EvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_6, + EvsParams evs2 = createEvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_6, CHANNEL_AWARE_MODE, USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); assertThat(evs1).isNotEqualTo(evs2); - EvsParams evs3 = new EvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, + EvsParams evs3 = createEvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, (byte)8, USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); assertThat(evs1).isNotEqualTo(evs3); - EvsParams evs4 = new EvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, + EvsParams evs4 = createEvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, CHANNEL_AWARE_MODE, false, USE_HEADER_FULL_ONLY_RX); assertThat(evs1).isNotEqualTo(evs4); - EvsParams evs5 = new EvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, + EvsParams evs5 = createEvsParams(EvsParams.EVS_WIDE_BAND, EvsParams.EVS_MODE_7, CHANNEL_AWARE_MODE, USE_HEADER_FULL_ONLY_TX, true); assertThat(evs1).isNotEqualTo(evs5); - EvsParams evs6 = new EvsParams(EvsParams.EVS_SUPER_WIDE_BAND, EvsParams.EVS_MODE_7, + EvsParams evs6 = createEvsParams(EvsParams.EVS_SUPER_WIDE_BAND, EvsParams.EVS_MODE_7, CHANNEL_AWARE_MODE, USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); assertThat(evs1).isNotEqualTo(evs6); |