Add a randomized testcase for MediaPlayer.java API methods
Change-Id: I99cac3cbb30110a1393f196b70cd6a066c2f5cc5
diff --git a/tests/tests/media/src/android/media/cts/MediaRandomTest.java b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
index f1e3e8e..adee09d 100644
--- a/tests/tests/media/src/android/media/cts/MediaRandomTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
@@ -16,15 +16,30 @@
package android.media.cts;
+import com.android.cts.media.R;
+
import android.media.MediaRecorder;
import android.media.MediaPlayer;
import android.view.SurfaceHolder;
import android.test.ActivityInstrumentationTestCase2;
import android.os.Environment;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
import android.util.Log;
import java.util.Random;
+/**
+ * Tests for the MediaPlayer.java and MediaRecorder.java APIs
+ *
+ * These testcases make randomized calls to the public APIs available, and
+ * the focus is on whether the randomized calls can lead to crash in
+ * mediaserver process and/or ANRs.
+ *
+ * The files in res/raw used by testLocalVideo* are (c) copyright 2008,
+ * Blender Foundation / www.bigbuckbunny.org, and are licensed under the Creative Commons
+ * Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
+ */
public class MediaRandomTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
private static final String TAG = "MediaRandomTest";
@@ -32,9 +47,15 @@
Environment.getExternalStorageDirectory().toString() + "/record.3gp";
private static final int NUMBER_OF_RECORDER_RANDOM_ACTIONS = 100000;
+ private static final int NUMBER_OF_PLAYER_RANDOM_ACTIONS = 100000;
private MediaRecorder mRecorder;
- private volatile boolean mMediaServerDied = false;
+ private MediaPlayer mPlayer;
+ private SurfaceHolder mSurfaceHolder;
+ private Resources mResources;
+
+ // Modified across multiple threads
+ private volatile boolean mMediaServerDied;
private volatile int mAction;
private volatile int mParam;
@@ -42,12 +63,16 @@
protected void setUp() throws Exception {
super.setUp();
getInstrumentation().waitForIdleSync();
+ mMediaServerDied = false;
+ mSurfaceHolder = getActivity().getSurfaceHolder();
+ mResources = getInstrumentation().getTargetContext().getResources();
try {
// Running this on UI thread make sure that
// onError callback can be received.
runTestOnUiThread(new Runnable() {
public void run() {
mRecorder = new MediaRecorder();
+ mPlayer = new MediaPlayer();
}
});
} catch (Throwable e) {
@@ -62,6 +87,10 @@
mRecorder.release();
mRecorder = null;
}
+ if (mPlayer != null) {
+ mPlayer.release();
+ mPlayer = null;
+ }
super.tearDown();
}
@@ -132,7 +161,101 @@
super("com.android.cts.media", MediaStubActivity.class);
}
- public void testmRecorderRandomAction() throws Exception {
+ private void loadSource(int resid) throws Exception {
+ AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
+ try {
+ mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
+ afd.getLength());
+ } finally {
+ afd.close();
+ }
+ }
+
+ public void testPlayerRandomAction() throws Exception {
+ try {
+ mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+ @Override
+ public boolean onError(MediaPlayer mp, int what, int extra) {
+ if (mPlayer == mp &&
+ what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
+ Log.e(TAG, "mediaserver process died");
+ mMediaServerDied = true;
+ }
+ return true;
+ }
+ });
+ loadSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
+ mPlayer.setDisplay(mSurfaceHolder);
+ mPlayer.prepare();
+ mPlayer.start();
+
+ long seed = System.currentTimeMillis();
+ Log.v(TAG, "seed = " + seed);
+ Random r = new Random(seed);
+
+ Watchdog watchdog = new Watchdog(5000);
+ watchdog.start();
+ for (int i = 0; i < NUMBER_OF_PLAYER_RANDOM_ACTIONS; i++){
+ watchdog.ping();
+ assertTrue(!mMediaServerDied);
+
+ mAction = (int)(r.nextInt() % 12);
+ mParam = (int)(r.nextInt() % 1000000);
+ try {
+ switch (mAction) {
+ case 0:
+ mPlayer.getCurrentPosition();
+ break;
+ case 1:
+ mPlayer.getDuration();
+ break;
+ case 2:
+ mPlayer.getVideoHeight();
+ break;
+ case 3:
+ mPlayer.getVideoWidth();
+ break;
+ case 4:
+ mPlayer.isPlaying();
+ break;
+ case 5:
+ mPlayer.pause();
+ break;
+ case 6:
+ // Don't add mPlayer.prepare() call here for two reasons:
+ // 1. calling prepare() is a bad idea since it is a blocking call, and
+ // 2. when prepare() is in progress, mediaserver died message will not be sent to apps
+ mPlayer.prepareAsync();
+ break;
+ case 7:
+ mPlayer.seekTo((int)(mParam));
+ break;
+ case 8:
+ mPlayer.setLooping(mParam % 2 == 0);
+ break;
+ case 9:
+ mPlayer.setVolume((mParam % 1000) / 500.0f,
+ (mParam / 1000) / 500.0f);
+ break;
+ case 10:
+ mPlayer.start();
+ break;
+ case 11:
+ Thread.sleep(mParam % 20);
+ break;
+ }
+ } catch (Exception e) {
+ }
+ }
+ mPlayer.stop();
+ watchdog.end();
+ watchdog.join();
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ }
+
+ public void testRecorderRandomAction() throws Exception {
try {
long seed = System.currentTimeMillis();
Log.v(TAG, "seed = " + seed);
@@ -142,11 +265,8 @@
mRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {
@Override
public void onError(MediaRecorder recorder, int what, int extra) {
- // FIXME:
- // replace the constant with MediaRecorder.MEDIA_RECORDER_ERROR_SERVER_DIED,
- // if it becomes public.
if (mRecorder == recorder &&
- what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
+ what == MediaRecorder.MEDIA_ERROR_SERVER_DIED) {
Log.e(TAG, "mediaserver process died");
mMediaServerDied = true;
}
@@ -155,7 +275,6 @@
final int[] width = {176, 352, 320, 640, 1280, 1920};
final int[] height = {144, 288, 240, 480, 720, 1080};
- final SurfaceHolder surfaceHolder = getActivity().getSurfaceHolder();
Watchdog watchdog = new Watchdog(5000);
watchdog.start();
@@ -186,7 +305,7 @@
mRecorder.setVideoEncoder(mParam % 5);
break;
case 5:
- mRecorder.setPreviewDisplay(surfaceHolder.getSurface());
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
break;
case 6:
int index = mParam % width.length;