diff options
author | Jayachandran C <jayachandranc@google.com> | 2021-12-24 02:06:52 -0800 |
---|---|---|
committer | Jayachandran C <jayachandranc@google.com> | 2022-03-04 13:35:48 -0800 |
commit | 816f2638a9e86a01b91284a8dc0ca5c026ae12a5 (patch) | |
tree | 0bd8e81dc70f6b13548d14016e3ebf52b8d00354 /tests/unit | |
parent | 09f9a3a928c1b0821f253c16abec7f36ed4e5852 (diff) | |
download | ImsMedia-816f2638a9e86a01b91284a8dc0ca5c026ae12a5.tar.gz |
Initial implementation of ImsMedia APIs and services
Bug: 203240638
Test: atest
Change-Id: I3f980e3146f679722636e709a51182f232dcbd2f
Diffstat (limited to 'tests/unit')
8 files changed, 1003 insertions, 0 deletions
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp new file mode 100644 index 00000000..4ec313b6 --- /dev/null +++ b/tests/unit/Android.bp @@ -0,0 +1,38 @@ +// +// 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_test { + name: "ImsMediaJavaUnitTests", + srcs: ["src/**/*.java"], + manifest: "AndroidManifest.xml", + static_libs: [ + "imsmedia-core", + "android.telephony.imsmedia", + "androidx.test.core", + "androidx.test.ext.junit", + "androidx.test.rules", + "mockito-target-minus-junit4", + "platform-test-annotations", + "testables", + "testng", + "truth-prebuilt", + ], + certificate: "platform", + test_suites: ["device-tests"], +} diff --git a/tests/unit/AndroidManifest.xml b/tests/unit/AndroidManifest.xml new file mode 100644 index 00000000..6c500bef --- /dev/null +++ b/tests/unit/AndroidManifest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.telephony.imsmedia.tests"> + <application> + <uses-library android:name="android.test.runner" /> + </application> + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.telephony.imsmedia.tests" + android:label="Ims Media Tests"> + </instrumentation> +</manifest> diff --git a/tests/unit/src/com/android/telephony/imsmedia/AmrParamsTest.java b/tests/unit/src/com/android/telephony/imsmedia/AmrParamsTest.java new file mode 100644 index 00000000..14c6c41c --- /dev/null +++ b/tests/unit/src/com/android/telephony/imsmedia/AmrParamsTest.java @@ -0,0 +1,84 @@ +/** + * 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.tests; + +import static com.google.common.truth.Truth.assertThat; + +import android.os.Parcel; +import android.telephony.imsmedia.AmrParams; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.runner.RunWith; +import org.junit.Test; + +@RunWith(AndroidJUnit4.class) +public class AmrParamsTest { + private static final boolean OCTET_ALIGNED = true; + private static final int MAX_REDUNDANCY_MILLIS = 1001; + + @Test + public void testConstructorAndGetters() { + AmrParams amr = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, + MAX_REDUNDANCY_MILLIS); + + assertThat(amr.getAmrMode()).isEqualTo(AmrParams.AMR_MODE_5); + assertThat(amr.getOctetAligned()).isEqualTo(OCTET_ALIGNED); + assertThat(amr.getMaxRedundancyMillis()).isEqualTo(MAX_REDUNDANCY_MILLIS); + } + + @Test + public void testParcel() { + AmrParams amr = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, MAX_REDUNDANCY_MILLIS); + + Parcel parcel = Parcel.obtain(); + amr.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + AmrParams parcelConfig = AmrParams.CREATOR.createFromParcel(parcel); + assertThat(amr).isEqualTo(parcelConfig); + } + + @Test + public void testEqual() { + AmrParams amr1 = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, + MAX_REDUNDANCY_MILLIS); + + AmrParams amr2 = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, + MAX_REDUNDANCY_MILLIS); + + assertThat(amr1).isEqualTo(amr2); + } + + @Test + public void testNotEqual() { + AmrParams amr1 = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, + MAX_REDUNDANCY_MILLIS); + + AmrParams amr2 = new AmrParams(AmrParams.AMR_MODE_6, OCTET_ALIGNED, + MAX_REDUNDANCY_MILLIS); + + assertThat(amr1).isNotEqualTo(amr2); + + AmrParams amr3 = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, 1002); + + assertThat(amr1).isNotEqualTo(amr3); + + AmrParams amr4 = new AmrParams(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 new file mode 100644 index 00000000..c8eac8bf --- /dev/null +++ b/tests/unit/src/com/android/telephony/imsmedia/AudioConfigTest.java @@ -0,0 +1,178 @@ +/** + * 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 android.os.Parcel; +import android.net.InetAddresses; +import android.telephony.AccessNetworkConstants.AccessNetworkType; +import android.telephony.imsmedia.AudioConfig; +import android.telephony.imsmedia.AmrParams; +import android.telephony.imsmedia.EvsParams; +import android.telephony.imsmedia.RtcpConfig; +import android.telephony.imsmedia.RtpConfig; +import androidx.test.runner.AndroidJUnit4; + +import java.net.InetSocketAddress; + +import org.junit.runner.RunWith; +import org.junit.Test; + +@RunWith(AndroidJUnit4.class) +public class AudioConfigTest { + // AmrParams + private static final boolean OCTET_ALIGNED = true; + private static final int MAX_REDUNDANCY_MILLIS = 1001; + + // EvsParams + private static final byte CHANNEL_AWARE_MODE = 7; + private static final boolean USE_HEADER_FULL_ONLY_TX = true; + private static final boolean USE_HEADER_FULL_ONLY_RX = false; + + // RtcpConfig + private static final String CANONICAL_NAME = "name"; + private static final int RTCP_PORT = 3333; + private static final int RTCP_INTERVAL = 66; + + // AudioConfig + 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 SAMPLING_RATE = 98; + private static final byte PTIME = 99; + private static final byte MAX_PTIME = 100; + 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 RtcpConfig rtcp = new RtcpConfig.Builder() + .setCanonicalName(CANONICAL_NAME) + .setTransmitPort(RTCP_PORT) + .setIntervalSec(RTCP_INTERVAL) + .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 AmrParams amr = new AmrParams(AmrParams.AMR_MODE_5, OCTET_ALIGNED, + MAX_REDUNDANCY_MILLIS); + @Test + public void testConstructorAndGetters() { + AudioConfig config = createAudioConfig(); + + assertThat(config.getMediaDirection()).isEqualTo( + RtpConfig.MEDIA_DIRECTION_TRANSMIT_RECEIVE); + assertThat(config.getPtimeMillis()).isEqualTo(PTIME); + assertThat(config.getMaxPtimeMillis()).isEqualTo(MAX_PTIME); + assertThat(config.getTxCodecModeRequest()).isEqualTo(CMR); + 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.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.getRxPayloadTypeNumber()).isEqualTo(RX_PAYLOAD); + assertThat(config.getTxPayloadTypeNumber()).isEqualTo(TX_PAYLOAD); + assertThat(config.getSamplingRateKHz()).isEqualTo(SAMPLING_RATE); + assertThat(config.getDscp()).isEqualTo(DSCP); + } + + @Test + public void testParcel() { + AudioConfig config = createAudioConfig(); + + Parcel parcel = Parcel.obtain(); + config.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + AudioConfig parcelConfig = AudioConfig.CREATOR.createFromParcel(parcel); + assertThat(config).isEqualTo(parcelConfig); + } + + @Test + public void testEqual() { + AudioConfig config1 = createAudioConfig(); + + AudioConfig config2 = createAudioConfig(); + + assertThat(config1).isEqualTo(config2); + } + + @Test + public void testNotEqual() { + AudioConfig config1 = createAudioConfig(); + + AudioConfig config2 = new AudioConfig.Builder() + .setMediaDirection(RtpConfig.MEDIA_DIRECTION_TRANSMIT_RECEIVE) + .setAccessNetwork(AccessNetworkType.EUTRAN) + .setRemoteRtpAddress(new InetSocketAddress( + InetAddresses.parseNumericAddress(REMOTE_RTP_ADDRESS), REMOTE_RTP_PORT)) + .setRtcpConfig(rtcp) + .setMaxMtuBytes(MAX_MTU_BYTES) + .setDscp(DSCP) + .setRxPayloadTypeNumber(RX_PAYLOAD) + .setTxPayloadTypeNumber(TX_PAYLOAD) + .setSamplingRateKHz(SAMPLING_RATE) + .setPtimeMillis(PTIME) + .setMaxPtimeMillis(MAX_PTIME) + .setTxCodecModeRequest(CMR) + .setDtxEnabled(DTX_ENABLED) + .setCodecType(AudioConfig.CODEC_EVS) + .setDtmfPayloadTypeNumber(DTMF_PAYLOAD) + .setDtmfsamplingRateKHz(DTMF_SAMPLING_RATE) + .setAmrParams(amr) + .setEvsParams(evs) + .build(); + + assertThat(config1).isNotEqualTo(config2); + } + + static AudioConfig createAudioConfig() { + return new AudioConfig.Builder() + .setMediaDirection(RtpConfig.MEDIA_DIRECTION_TRANSMIT_RECEIVE) + .setAccessNetwork(AccessNetworkType.EUTRAN) + .setRemoteRtpAddress(new InetSocketAddress( + InetAddresses.parseNumericAddress(REMOTE_RTP_ADDRESS), REMOTE_RTP_PORT)) + .setRtcpConfig(rtcp) + .setMaxMtuBytes(MAX_MTU_BYTES) + .setDscp(DSCP) + .setRxPayloadTypeNumber(RX_PAYLOAD) + .setTxPayloadTypeNumber(TX_PAYLOAD) + .setSamplingRateKHz(SAMPLING_RATE) + .setPtimeMillis(PTIME) + .setMaxPtimeMillis(MAX_PTIME) + .setTxCodecModeRequest(CMR) + .setDtxEnabled(DTX_ENABLED) + .setCodecType(AudioConfig.CODEC_EVS) + .setDtmfPayloadTypeNumber(DTMF_PAYLOAD) + .setDtmfsamplingRateKHz(DTMF_SAMPLING_RATE) + .setEvsParams(evs) + .build(); + } +} diff --git a/tests/unit/src/com/android/telephony/imsmedia/AudioSessionTest.java b/tests/unit/src/com/android/telephony/imsmedia/AudioSessionTest.java new file mode 100644 index 00000000..dca14f66 --- /dev/null +++ b/tests/unit/src/com/android/telephony/imsmedia/AudioSessionTest.java @@ -0,0 +1,317 @@ +/** + * 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.Mockito.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.os.Looper; +import android.os.Message; +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.util.ArrayList; + +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.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(JUnit4.class) +public class AudioSessionTest { + 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 FAILURE = ImsMediaSession.RESULT_FAILURE; + 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 AudioSession.AudioSessionHandler handler; + @Mock + private AudioService audioService; + @Mock + private IImsAudioSessionCallback callback; + private TestableLooper looper; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + audioSession = new AudioSession(SESSION_ID, callback, audioService); + handler = audioSession.getAudioSessionHandler(); + 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() { + OpenSessionParams params = new OpenSessionParams(); + audioSession.openSession(params); + processAllMessages(); + verify(audioService, times(1)).openSession(eq(SESSION_ID), eq(params)); + } + + @Test + public void testCloseSession() { + audioSession.closeSession(); + processAllMessages(); + verify(audioService, times(1)).closeSession(eq(SESSION_ID)); + } + + @Test + public void testGetSessionState() { + assertThat(audioSession.getSessionId()).isEqualTo(SESSION_ID); + assertThat(audioSession.getSessionState()).isEqualTo(ImsMediaSession.SESSION_STATE_CLOSED); + Utils.sendMessage(handler, AudioSession.EVENT_SESSION_CHANGED_IND, + ImsMediaSession.SESSION_STATE_OPEN); + processAllMessages(); + assertThat(audioSession.getSessionState()).isEqualTo(ImsMediaSession.SESSION_STATE_OPEN); + } + + @Test + public void testModifySession() { + // Modify Session Request + AudioConfig config = AudioConfigTest.createAudioConfig(); + audioSession.modifySession(config); + processAllMessages(); + verify(audioService, times(1)).modifySession(eq(config)); + + // Modify Session Response - SUCCESS + Utils.sendMessage(handler, AudioSession.EVENT_MODIFY_SESSION_RESPONSE, + SUCCESS, UNUSED, config); + processAllMessages(); + try { + verify(callback, times(1)).onModifySessionResponse(eq(config), eq(SUCCESS)); + } catch(RemoteException e) { + fail("Failed to notify modifySessionResponse: " + e); + } + + // Modify Session Response - FAILURE + Utils.sendMessage(handler, AudioSession.EVENT_MODIFY_SESSION_RESPONSE, + FAILURE, UNUSED, config); + processAllMessages(); + try { + verify(callback, times(1)).onModifySessionResponse(eq(config), eq(FAILURE)); + } catch(RemoteException e) { + fail("Failed to notify modifySessionResponse: " + e); + } + } + + @Test + public void testAddConfig() { + // Add Config Request + AudioConfig config = AudioConfigTest.createAudioConfig(); + audioSession.addConfig(config); + processAllMessages(); + verify(audioService, times(1)).addConfig(eq(config)); + + // Add Config Response - SUCCESS + Utils.sendMessage(handler, AudioSession.EVENT_ADD_CONFIG_RESPONSE, SUCCESS, UNUSED, config); + processAllMessages(); + try { + verify(callback, times(1)).onAddConfigResponse(eq(config), eq(SUCCESS)); + } catch(RemoteException e) { + fail("Failed to notify addConfigResponse: " + e); + } + + // Add Config Response - FAILURE + Utils.sendMessage(handler, AudioSession.EVENT_ADD_CONFIG_RESPONSE, FAILURE, UNUSED, config); + processAllMessages(); + try { + verify(callback, times(1)).onAddConfigResponse(eq(config), eq(FAILURE)); + } catch(RemoteException e) { + fail("Failed to notify addConfigResponse: " + e); + } + } + + @Test + public void testDeleteConfig() { + // Delete Config Request + AudioConfig config = AudioConfigTest.createAudioConfig(); + audioSession.deleteConfig(config); + processAllMessages(); + verify(audioService, times(1)).deleteConfig(eq(config)); + } + + @Test + public void testConfirmConfig() { + // Confirm Config Request + AudioConfig config = AudioConfigTest.createAudioConfig(); + audioSession.confirmConfig(config); + processAllMessages(); + verify(audioService, times(1)).confirmConfig(eq(config)); + + // Confirm Config Response - SUCCESS + Utils.sendMessage(handler, AudioSession.EVENT_CONFIRM_CONFIG_RESPONSE, + SUCCESS, UNUSED, config); + processAllMessages(); + try { + verify(callback, times(1)).onConfirmConfigResponse(eq(config), eq(SUCCESS)); + } catch(RemoteException e) { + fail("Failed to notify confirmConfigResponse: " + e); + } + + // Confirm Config Response - FAILURE + Utils.sendMessage(handler, AudioSession.EVENT_CONFIRM_CONFIG_RESPONSE, + FAILURE, UNUSED, config); + processAllMessages(); + try { + verify(callback, times(1)).onConfirmConfigResponse(eq(config), eq(FAILURE)); + } catch(RemoteException e) { + fail("Failed to notify confirmConfigResponse: " + e); + } + } + + @Test + public void testStartDtmf() { + audioSession.startDtmf(DTMF_DIGIT, DTMF_VOL, DTMF_DURATION); + processAllMessages(); + verify(audioService, times(1)).startDtmf(eq(DTMF_DIGIT), eq(DTMF_VOL), eq(DTMF_DURATION)); + } + + @Test + public void testStopDtmf() { + audioSession.stopDtmf(); + processAllMessages(); + verify(audioService, times(1)).stopDtmf(); + } + + @Test + public void testSetMediaQualityThreshold() { + // Set Media Quality Threshold + MediaQualityThreshold threshold = MediaQualityThresholdTest.createMediaQualityThreshold(); + audioSession.setMediaQualityThreshold(threshold); + processAllMessages(); + verify(audioService, times(1)).setMediaQualityThreshold(eq(threshold)); + } + + @Test + public void testMediaInactivityInd() { + // Receive Inactivity - RTP + Utils.sendMessage(handler, AudioSession.EVENT_MEDIA_INACTIVITY_IND, + 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 + Utils.sendMessage(handler, AudioSession.EVENT_MEDIA_INACTIVITY_IND, + 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 + Utils.sendMessage(handler, AudioSession.EVENT_PACKET_LOSS_IND, 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 + Utils.sendMessage(handler, AudioSession.EVENT_JITTER_IND, JITTER); + processAllMessages(); + try { + verify(callback, times(1)).notifyJitter(eq(JITTER)); + } catch(RemoteException e) { + fail("Failed to notify notifyJitter: " + e); + } + } + + @Test + public void testFirstMediaPacketReceivedInd() { + // Receive First MediaPacket Received Indication + AudioConfig config = AudioConfigTest.createAudioConfig(); + Utils.sendMessage(handler, AudioSession.EVENT_FIRST_MEDIA_PACKET_IND, config); + processAllMessages(); + try { + verify(callback, times(1)).onFirstMediaPacketReceived(eq(config)); + } catch(RemoteException e) { + fail("Failed to notify onFirstMediaPacketReceived: " + e); + } + } + + @Test + public void testHeaderExtension() { + // Send RtpHeaderExtension + ArrayList extensions = new ArrayList<RtpHeaderExtension>(); + audioSession.sendHeaderExtension(extensions); + processAllMessages(); + verify(audioService, times(1)).sendHeaderExtension(eq(extensions)); + + // Receive RtpHeaderExtension + Utils.sendMessage(handler, AudioSession.EVENT_RTP_HEADER_EXTENSION_IND, extensions); + processAllMessages(); + try { + verify(callback, times(1)).onHeaderExtensionReceived(eq(extensions)); + } 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/EvsParamsTest.java b/tests/unit/src/com/android/telephony/imsmedia/EvsParamsTest.java new file mode 100644 index 00000000..d07cd9dd --- /dev/null +++ b/tests/unit/src/com/android/telephony/imsmedia/EvsParamsTest.java @@ -0,0 +1,100 @@ +/** + * 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.tests; + +import static com.google.common.truth.Truth.assertThat; + +import android.os.Parcel; +import android.telephony.imsmedia.EvsParams; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.runner.RunWith; +import org.junit.Test; + +@RunWith(AndroidJUnit4.class) +public class EvsParamsTest { + private static final byte CHANNEL_AWARE_MODE = 7; + private static final boolean USE_HEADER_FULL_ONLY_TX = true; + private static final boolean USE_HEADER_FULL_ONLY_RX = false; + + @Test + public void testConstructorAndGetters() { + EvsParams evs = new EvsParams(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); + assertThat(evs.getEvsMode()).isEqualTo(EvsParams.EVS_MODE_7); + assertThat(evs.getChannelAwareMode()).isEqualTo(CHANNEL_AWARE_MODE); + assertThat(evs.getUseHeaderFullOnlyOnTx()).isEqualTo(USE_HEADER_FULL_ONLY_TX); + assertThat(evs.getUseHeaderFullOnlyOnRx()).isEqualTo(USE_HEADER_FULL_ONLY_RX); + } + + @Test + public void testParcel() { + EvsParams evs = new EvsParams(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(); + evs.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + EvsParams parcelConfig = EvsParams.CREATOR.createFromParcel(parcel); + assertThat(evs).isEqualTo(parcelConfig); + } + + @Test + public void testEqual() { + EvsParams evs1 = new EvsParams(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, + CHANNEL_AWARE_MODE, USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); + + assertThat(evs1).isEqualTo(evs2); + } + + @Test + public void testNotEqual() { + EvsParams evs1 = new EvsParams(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, + 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, + (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, + 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, + 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, + CHANNEL_AWARE_MODE, USE_HEADER_FULL_ONLY_TX, USE_HEADER_FULL_ONLY_RX); + + assertThat(evs1).isNotEqualTo(evs6); + } +} diff --git a/tests/unit/src/com/android/telephony/imsmedia/MediaQualityThresholdTest.java b/tests/unit/src/com/android/telephony/imsmedia/MediaQualityThresholdTest.java new file mode 100644 index 00000000..dc3859e5 --- /dev/null +++ b/tests/unit/src/com/android/telephony/imsmedia/MediaQualityThresholdTest.java @@ -0,0 +1,129 @@ +/** + * 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 android.os.Parcel; +import android.telephony.imsmedia.MediaQualityThreshold; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.runner.RunWith; +import org.junit.Test; + +@RunWith(AndroidJUnit4.class) +public class MediaQualityThresholdTest { + private static final int RTP_TIMEOUT = 20; + private static final int RTCP_TIMEOUT = 60; + private static final int PACKET_LOSS_PERIOD = 120; + private static final int PACKET_LOSS_RATE = 10; + private static final int JITTER_PERIOD = 160; + private static final int JITTER_THRESHOLD = 200; + + @Test + public void testConstructorAndGetters() { + MediaQualityThreshold threshold = createMediaQualityThreshold(); + + assertThat(threshold.getRtpInactivityTimerMillis()).isEqualTo(RTP_TIMEOUT); + assertThat(threshold.getRtcpInactivityTimerMillis()).isEqualTo(RTCP_TIMEOUT); + assertThat(threshold.getPacketLossPeriodMillis()).isEqualTo(PACKET_LOSS_PERIOD); + assertThat(threshold.getPacketLossThreshold()).isEqualTo(PACKET_LOSS_RATE); + assertThat(threshold.getJitterPeriodMillis()).isEqualTo(JITTER_PERIOD); + assertThat(threshold.getJitterThresholdMillis()).isEqualTo(JITTER_THRESHOLD); + } + + @Test + public void testParcel() { + MediaQualityThreshold threshold = createMediaQualityThreshold(); + + Parcel parcel = Parcel.obtain(); + threshold.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + MediaQualityThreshold parcelConfig = MediaQualityThreshold.CREATOR.createFromParcel(parcel); + assertThat(threshold).isEqualTo(parcelConfig); + } + + @Test + public void testEqual() { + MediaQualityThreshold threshold1 = createMediaQualityThreshold(); + MediaQualityThreshold threshold2 = createMediaQualityThreshold(); + + assertThat(threshold1).isEqualTo(threshold2); + } + + @Test + public void testNotEqual() { + MediaQualityThreshold threshold1 = createMediaQualityThreshold(); + + MediaQualityThreshold threshold2 = new MediaQualityThreshold.Builder() + .setRtpInactivityTimerMillis(RTP_TIMEOUT) + .setRtcpInactivityTimerMillis(RTCP_TIMEOUT) + .setPacketLossPeriodMillis(PACKET_LOSS_PERIOD) + .setPacketLossThreshold(PACKET_LOSS_RATE) + .setJitterPeriodMillis(JITTER_PERIOD) + .setJitterThresholdMillis(JITTER_THRESHOLD+1) + .build(); + + assertThat(threshold1).isNotEqualTo(threshold2); + + MediaQualityThreshold threshold3 = new MediaQualityThreshold.Builder() + .setRtpInactivityTimerMillis(RTP_TIMEOUT) + .setRtcpInactivityTimerMillis(RTCP_TIMEOUT) + .setPacketLossPeriodMillis(PACKET_LOSS_PERIOD) + .setPacketLossThreshold(PACKET_LOSS_RATE) + .setJitterPeriodMillis(JITTER_PERIOD+1) + .setJitterThresholdMillis(JITTER_THRESHOLD) + .build(); + + assertThat(threshold1).isNotEqualTo(threshold3); + + MediaQualityThreshold threshold4 = new MediaQualityThreshold.Builder() + .setRtpInactivityTimerMillis(RTP_TIMEOUT) + .setRtcpInactivityTimerMillis(RTCP_TIMEOUT+1) + .setPacketLossPeriodMillis(PACKET_LOSS_PERIOD) + .setPacketLossThreshold(PACKET_LOSS_RATE) + .setJitterPeriodMillis(JITTER_PERIOD) + .setJitterThresholdMillis(JITTER_THRESHOLD) + .build(); + + assertThat(threshold1).isNotEqualTo(threshold4); + + MediaQualityThreshold threshold5 = new MediaQualityThreshold.Builder() + .setRtpInactivityTimerMillis(RTP_TIMEOUT+1) + .setRtcpInactivityTimerMillis(RTCP_TIMEOUT) + .setPacketLossPeriodMillis(PACKET_LOSS_PERIOD) + .setPacketLossThreshold(PACKET_LOSS_RATE) + .setJitterPeriodMillis(JITTER_PERIOD) + .setJitterThresholdMillis(JITTER_THRESHOLD) + .build(); + + assertThat(threshold1).isNotEqualTo(threshold5); + } + + static MediaQualityThreshold createMediaQualityThreshold() { + return new MediaQualityThreshold.Builder() + .setRtpInactivityTimerMillis(RTP_TIMEOUT) + .setRtcpInactivityTimerMillis(RTCP_TIMEOUT) + .setPacketLossPeriodMillis(PACKET_LOSS_PERIOD) + .setPacketLossThreshold(PACKET_LOSS_RATE) + .setJitterPeriodMillis(JITTER_PERIOD) + .setJitterThresholdMillis(JITTER_THRESHOLD) + .build(); + } +} diff --git a/tests/unit/src/com/android/telephony/imsmedia/RtcpConfigTest.java b/tests/unit/src/com/android/telephony/imsmedia/RtcpConfigTest.java new file mode 100644 index 00000000..ea409705 --- /dev/null +++ b/tests/unit/src/com/android/telephony/imsmedia/RtcpConfigTest.java @@ -0,0 +1,132 @@ +/** + * 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.tests; + +import static com.google.common.truth.Truth.assertThat; + +import android.os.Parcel; +import android.telephony.imsmedia.RtcpConfig; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.runner.RunWith; +import org.junit.Test; + +@RunWith(AndroidJUnit4.class) +public class RtcpConfigTest { + private static final String NAME = "name"; + private static final int PORT = 3333; + private static final int INTERVAL = 66; + private static final int BLOCK_TYPES = RtcpConfig.FLAG_RTCPXR_DLRR_REPORT_BLOCK; + + @Test + public void testConstructorAndGetters() { + RtcpConfig rtcp = new RtcpConfig.Builder() + .setCanonicalName(NAME) + .setTransmitPort(PORT) + .setIntervalSec(INTERVAL) + .setRtcpXrBlockTypes(BLOCK_TYPES) + .build(); + + assertThat(rtcp.getCanonicalName()).isEqualTo(NAME); + assertThat(rtcp.getTransmitPort()).isEqualTo(PORT); + assertThat(rtcp.getIntervalSec()).isEqualTo(INTERVAL); + assertThat(rtcp.getRtcpXrBlockTypes()).isEqualTo(BLOCK_TYPES); + } + + @Test + public void testParcel() { + RtcpConfig rtcp = new RtcpConfig.Builder() + .setCanonicalName(NAME) + .setTransmitPort(PORT) + .setIntervalSec(INTERVAL) + .setRtcpXrBlockTypes(BLOCK_TYPES) + .build(); + + Parcel parcel = Parcel.obtain(); + rtcp.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + RtcpConfig parcelConfig = RtcpConfig.CREATOR.createFromParcel(parcel); + assertThat(rtcp).isEqualTo(parcelConfig); + } + + @Test + public void testEqual() { + RtcpConfig rtcp1 = new RtcpConfig.Builder() + .setCanonicalName(NAME) + .setTransmitPort(PORT) + .setIntervalSec(INTERVAL) + .setRtcpXrBlockTypes(BLOCK_TYPES) + .build(); + + RtcpConfig rtcp2 = new RtcpConfig.Builder() + .setCanonicalName(NAME) + .setTransmitPort(PORT) + .setIntervalSec(INTERVAL) + .setRtcpXrBlockTypes(BLOCK_TYPES) + .build(); + + assertThat(rtcp1).isEqualTo(rtcp2); + } + + @Test + public void testNotEqual() { + RtcpConfig rtcp1 = new RtcpConfig.Builder() + .setCanonicalName(NAME) + .setTransmitPort(PORT) + .setIntervalSec(INTERVAL) + .setRtcpXrBlockTypes(BLOCK_TYPES) + .build(); + + RtcpConfig rtcp2 = new RtcpConfig.Builder() + .setCanonicalName(NAME) + .setTransmitPort(3334) + .setIntervalSec(INTERVAL) + .setRtcpXrBlockTypes(BLOCK_TYPES) + .build(); + + assertThat(rtcp1).isNotEqualTo(rtcp2); + + RtcpConfig rtcp3 = new RtcpConfig.Builder() + .setCanonicalName("differs") + .setTransmitPort(PORT) + .setIntervalSec(INTERVAL) + .setRtcpXrBlockTypes(BLOCK_TYPES) + .build(); + + assertThat(rtcp1).isNotEqualTo(rtcp3); + + RtcpConfig rtcp4 = new RtcpConfig.Builder() + .setCanonicalName(NAME) + .setTransmitPort(PORT) + .setIntervalSec(60) + .setRtcpXrBlockTypes(BLOCK_TYPES) + .build(); + + assertThat(rtcp1).isNotEqualTo(rtcp4); + + RtcpConfig rtcp5 = new RtcpConfig.Builder() + .setCanonicalName(NAME) + .setTransmitPort(PORT) + .setIntervalSec(INTERVAL) + .setRtcpXrBlockTypes(RtcpConfig.FLAG_RTCPXR_NONE) + .build(); + + assertThat(rtcp1).isNotEqualTo(rtcp5); + } +} |