Add CTS test for android.net.rtp.
Bug: 5975113
Change-Id: I20ec3b172a2d6501048418f4c3da06d1b7144fd3
diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml
index 4fa0565..b3556f5 100644
--- a/tests/cts/net/AndroidManifest.xml
+++ b/tests/cts/net/AndroidManifest.xml
@@ -23,6 +23,7 @@
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioCodecTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioCodecTest.java
new file mode 100644
index 0000000..412498c
--- /dev/null
+++ b/tests/cts/net/src/android/net/rtp/cts/AudioCodecTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012 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 android.net.rtp.cts;
+
+import android.net.rtp.AudioCodec;
+import android.test.AndroidTestCase;
+
+public class AudioCodecTest extends AndroidTestCase {
+
+ private void assertEquals(AudioCodec codec, int type, String rtpmap, String fmtp) {
+ if (type >= 0) {
+ assertEquals(codec.type, type);
+ } else {
+ assertTrue(codec.type >= 96 && codec.type <= 127);
+ }
+ assertEquals(codec.rtpmap.compareToIgnoreCase(rtpmap), 0);
+ assertEquals(codec.fmtp, fmtp);
+ }
+
+ public void testConstants() throws Exception {
+ assertEquals(AudioCodec.PCMU, 0, "PCMU/8000", null);
+ assertEquals(AudioCodec.PCMA, 8, "PCMA/8000", null);
+ assertEquals(AudioCodec.GSM, 3, "GSM/8000", null);
+ assertEquals(AudioCodec.GSM_EFR, -1, "GSM-EFR/8000", null);
+ assertEquals(AudioCodec.AMR, -1, "AMR/8000", null);
+
+ assertFalse(AudioCodec.AMR.type == AudioCodec.GSM_EFR.type);
+ }
+
+ public void testGetCodec() throws Exception {
+ // Bad types.
+ assertNull(AudioCodec.getCodec(128, "PCMU/8000", null));
+ assertNull(AudioCodec.getCodec(-1, "PCMU/8000", null));
+ assertNull(AudioCodec.getCodec(96, null, null));
+
+ // Fixed types.
+ assertEquals(AudioCodec.getCodec(0, null, null), 0, "PCMU/8000", null);
+ assertEquals(AudioCodec.getCodec(8, null, null), 8, "PCMA/8000", null);
+ assertEquals(AudioCodec.getCodec(3, null, null), 3, "GSM/8000", null);
+
+ // Dynamic types.
+ assertEquals(AudioCodec.getCodec(96, "pcmu/8000", null), 96, "PCMU/8000", null);
+ assertEquals(AudioCodec.getCodec(97, "pcma/8000", null), 97, "PCMA/8000", null);
+ assertEquals(AudioCodec.getCodec(98, "gsm/8000", null), 98, "GSM/8000", null);
+ assertEquals(AudioCodec.getCodec(99, "gsm-efr/8000", null), 99, "GSM-EFR/8000", null);
+ assertEquals(AudioCodec.getCodec(100, "amr/8000", null), 100, "AMR/8000", null);
+ }
+
+ public void testGetCodecs() throws Exception {
+ AudioCodec[] codecs = AudioCodec.getCodecs();
+ assertTrue(codecs.length >= 5);
+
+ // The types of the codecs should be different.
+ boolean[] types = new boolean[128];
+ for (AudioCodec codec : codecs) {
+ assertFalse(types[codec.type]);
+ types[codec.type] = true;
+ }
+ }
+}
diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java
new file mode 100644
index 0000000..f06d7e9
--- /dev/null
+++ b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2012 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 android.net.rtp.cts;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.net.rtp.AudioCodec;
+import android.net.rtp.AudioGroup;
+import android.net.rtp.AudioStream;
+import android.net.rtp.RtpStream;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+
+public class AudioGroupTest extends AndroidTestCase {
+
+ private static final String TAG = AudioGroupTest.class.getSimpleName();
+
+ private AudioManager mAudioManager;
+
+ private AudioStream mStreamA;
+ private DatagramSocket mSocketA;
+ private AudioStream mStreamB;
+ private DatagramSocket mSocketB;
+ private AudioGroup mGroup;
+
+ @Override
+ public void setUp() throws Exception {
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+
+ InetAddress local = InetAddress.getByName("::1");
+
+ mStreamA = new AudioStream(local);
+ mStreamA.setMode(RtpStream.MODE_NORMAL);
+ mStreamA.setCodec(AudioCodec.PCMU);
+ mSocketA = new DatagramSocket();
+ mSocketA.connect(mStreamA.getLocalAddress(), mStreamA.getLocalPort());
+ mStreamA.associate(mSocketA.getLocalAddress(), mSocketA.getLocalPort());
+
+ mStreamB = new AudioStream(local);
+ mStreamB.setMode(RtpStream.MODE_NORMAL);
+ mStreamB.setCodec(AudioCodec.PCMU);
+ mSocketB = new DatagramSocket();
+ mSocketB.connect(mStreamB.getLocalAddress(), mStreamB.getLocalPort());
+ mStreamB.associate(mSocketB.getLocalAddress(), mSocketB.getLocalPort());
+
+ mGroup = new AudioGroup();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ mGroup.clear();
+ mStreamA.release();
+ mSocketA.close();
+ mStreamB.release();
+ mSocketB.close();
+ mAudioManager.setMode(AudioManager.MODE_NORMAL);
+ }
+
+ private void assertPacket(DatagramSocket socket, int length) throws Exception {
+ DatagramPacket packet = new DatagramPacket(new byte[length + 1], length + 1);
+ socket.setSoTimeout(3000);
+ socket.receive(packet);
+ assertEquals(packet.getLength(), length);
+ }
+
+ private void drain(DatagramSocket socket) throws Exception {
+ DatagramPacket packet = new DatagramPacket(new byte[1], 1);
+ socket.setSoTimeout(1);
+ try {
+ // Drain the socket by retrieving all the packets queued on it.
+ // A SocketTimeoutException will be thrown when it becomes empty.
+ while (true) {
+ socket.receive(packet);
+ }
+ } catch (Exception e) {
+ // ignore.
+ }
+ }
+
+ public void testTraffic() throws Exception {
+ mStreamA.join(mGroup);
+ assertPacket(mSocketA, 12 + 160);
+
+ mStreamB.join(mGroup);
+ assertPacket(mSocketB, 12 + 160);
+
+ mStreamA.join(null);
+ drain(mSocketA);
+
+ drain(mSocketB);
+ assertPacket(mSocketB, 12 + 160);
+
+ mStreamA.join(mGroup);
+ assertPacket(mSocketA, 12 + 160);
+ }
+
+ public void testSetMode() throws Exception {
+ mGroup.setMode(AudioGroup.MODE_NORMAL);
+ assertEquals(mGroup.getMode(), AudioGroup.MODE_NORMAL);
+
+ mGroup.setMode(AudioGroup.MODE_MUTED);
+ assertEquals(mGroup.getMode(), AudioGroup.MODE_MUTED);
+
+ mStreamA.join(mGroup);
+ mStreamB.join(mGroup);
+
+ mGroup.setMode(AudioGroup.MODE_NORMAL);
+ assertEquals(mGroup.getMode(), AudioGroup.MODE_NORMAL);
+
+ mGroup.setMode(AudioGroup.MODE_MUTED);
+ assertEquals(mGroup.getMode(), AudioGroup.MODE_MUTED);
+ }
+
+ public void testAdd() throws Exception {
+ mStreamA.join(mGroup);
+ assertEquals(mGroup.getStreams().length, 1);
+
+ mStreamB.join(mGroup);
+ assertEquals(mGroup.getStreams().length, 2);
+
+ mStreamA.join(mGroup);
+ assertEquals(mGroup.getStreams().length, 2);
+ }
+
+ public void testRemove() throws Exception {
+ mStreamA.join(mGroup);
+ assertEquals(mGroup.getStreams().length, 1);
+
+ mStreamA.join(null);
+ assertEquals(mGroup.getStreams().length, 0);
+
+ mStreamA.join(mGroup);
+ assertEquals(mGroup.getStreams().length, 1);
+ }
+
+ public void testClear() throws Exception {
+ mStreamA.join(mGroup);
+ mStreamB.join(mGroup);
+ mGroup.clear();
+
+ assertEquals(mGroup.getStreams().length, 0);
+ assertFalse(mStreamA.isBusy());
+ assertFalse(mStreamB.isBusy());
+ }
+
+ public void testDoubleClear() throws Exception {
+ mStreamA.join(mGroup);
+ mStreamB.join(mGroup);
+ mGroup.clear();
+ mGroup.clear();
+ }
+}
diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java
new file mode 100644
index 0000000..323b022
--- /dev/null
+++ b/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2012 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 android.net.rtp.cts;
+
+import android.net.rtp.AudioCodec;
+import android.net.rtp.AudioStream;
+import android.test.AndroidTestCase;
+
+import java.net.InetAddress;
+
+public class AudioStreamTest extends AndroidTestCase {
+
+ private void testRtpStream(InetAddress address) throws Exception {
+ AudioStream stream = new AudioStream(address);
+ assertEquals(stream.getLocalAddress(), address);
+ assertEquals(stream.getLocalPort() % 2, 0);
+
+ assertNull(stream.getRemoteAddress());
+ assertEquals(stream.getRemotePort(), -1);
+ stream.associate(address, 1000);
+ assertEquals(stream.getRemoteAddress(), address);
+ assertEquals(stream.getRemotePort(), 1000);
+
+ assertFalse(stream.isBusy());
+ stream.release();
+ }
+
+ public void testV4Stream() throws Exception {
+ testRtpStream(InetAddress.getByName("127.0.0.1"));
+ }
+
+ public void testV6Stream() throws Exception {
+ testRtpStream(InetAddress.getByName("::1"));
+ }
+
+ public void testSetDtmfType() throws Exception {
+ AudioStream stream = new AudioStream(InetAddress.getByName("::1"));
+
+ assertEquals(stream.getDtmfType(), -1);
+ try {
+ stream.setDtmfType(0);
+ fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // ignore
+ }
+ stream.setDtmfType(96);
+ assertEquals(stream.getDtmfType(), 96);
+
+ stream.setCodec(AudioCodec.getCodec(97, "PCMU/8000", null));
+ try {
+ stream.setDtmfType(97);
+ fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // ignore
+ }
+ stream.release();
+ }
+
+ public void testSetCodec() throws Exception {
+ AudioStream stream = new AudioStream(InetAddress.getByName("::1"));
+
+ assertNull(stream.getCodec());
+ stream.setCodec(AudioCodec.getCodec(97, "PCMU/8000", null));
+ assertNotNull(stream.getCodec());
+
+ stream.setDtmfType(96);
+ try {
+ stream.setCodec(AudioCodec.getCodec(96, "PCMU/8000", null));
+ fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // ignore
+ }
+ stream.release();
+ }
+
+ public void testDoubleRelease() throws Exception {
+ AudioStream stream = new AudioStream(InetAddress.getByName("::1"));
+ stream.release();
+ stream.release();
+ }
+}