summaryrefslogtreecommitdiff
path: root/tests/unit
diff options
context:
space:
mode:
authorJayachandran C <jayachandranc@google.com>2021-12-24 02:06:52 -0800
committerJayachandran C <jayachandranc@google.com>2022-03-04 13:35:48 -0800
commit816f2638a9e86a01b91284a8dc0ca5c026ae12a5 (patch)
tree0bd8e81dc70f6b13548d14016e3ebf52b8d00354 /tests/unit
parent09f9a3a928c1b0821f253c16abec7f36ed4e5852 (diff)
downloadImsMedia-816f2638a9e86a01b91284a8dc0ca5c026ae12a5.tar.gz
Initial implementation of ImsMedia APIs and services
Bug: 203240638 Test: atest Change-Id: I3f980e3146f679722636e709a51182f232dcbd2f
Diffstat (limited to 'tests/unit')
-rw-r--r--tests/unit/Android.bp38
-rw-r--r--tests/unit/AndroidManifest.xml25
-rw-r--r--tests/unit/src/com/android/telephony/imsmedia/AmrParamsTest.java84
-rw-r--r--tests/unit/src/com/android/telephony/imsmedia/AudioConfigTest.java178
-rw-r--r--tests/unit/src/com/android/telephony/imsmedia/AudioSessionTest.java317
-rw-r--r--tests/unit/src/com/android/telephony/imsmedia/EvsParamsTest.java100
-rw-r--r--tests/unit/src/com/android/telephony/imsmedia/MediaQualityThresholdTest.java129
-rw-r--r--tests/unit/src/com/android/telephony/imsmedia/RtcpConfigTest.java132
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);
+ }
+}