am a0837ad6: am 0aa645dd: Merge "Add a randomized testcase on most of the MediaRecorder public methods" into jb-mr1-dev

* commit 'a0837ad6163cb106f172d06114fed3cdccef7896':
  Add a randomized testcase on most of the MediaRecorder public methods
diff --git a/tests/tests/media/src/android/media/cts/MediaRandomTest.java b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
new file mode 100644
index 0000000..f1e3e8e
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
@@ -0,0 +1,228 @@
+/*
+ * 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.media.cts;
+
+
+import android.media.MediaRecorder;
+import android.media.MediaPlayer;
+import android.view.SurfaceHolder;
+import android.test.ActivityInstrumentationTestCase2;
+import android.os.Environment;
+import android.util.Log;
+
+import java.util.Random;
+
+public class MediaRandomTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
+    private static final String TAG = "MediaRandomTest";
+
+    private static final String OUTPUT_FILE =
+                Environment.getExternalStorageDirectory().toString() + "/record.3gp";
+
+    private static final int NUMBER_OF_RECORDER_RANDOM_ACTIONS = 100000;
+
+    private MediaRecorder mRecorder;
+    private volatile boolean mMediaServerDied = false;
+    private volatile int mAction;
+    private volatile int mParam;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        getInstrumentation().waitForIdleSync();
+        try {
+            // Running this on UI thread make sure that
+            // onError callback can be received.
+            runTestOnUiThread(new Runnable() {
+                public void run() {
+                    mRecorder = new MediaRecorder();
+                }
+            });
+        } catch (Throwable e) {
+            e.printStackTrace();
+            fail();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mRecorder != null) {
+            mRecorder.release();
+            mRecorder = null;
+        }
+        super.tearDown();
+    }
+
+    /**
+     * This is a watchdog used to stop the process if it hasn't been pinged
+     * for more than specified milli-seconds. It is used like:
+     *
+     * Watchdog w = new Watchdog(10000);  // 10 seconds.
+     * w.start();       // start the watchdog.
+     * ...
+     * w.ping();
+     * ...
+     * w.ping();
+     * ...
+     * w.end();        // ask the watchdog to stop.
+     * w.join();        // join the thread.
+     */
+    class Watchdog extends Thread {
+        private final long mTimeoutMs;
+        private boolean mWatchdogStop;
+        private boolean mWatchdogPinged;
+
+        public Watchdog(long timeoutMs) {
+            mTimeoutMs = timeoutMs;
+            mWatchdogStop = false;
+            mWatchdogPinged = false;
+        }
+
+        public synchronized void run() {
+            while (true) {
+                // avoid early termination by "spurious" waitup.
+                final long startTimeMs = System.currentTimeMillis();
+                long remainingWaitTimeMs = mTimeoutMs;
+                do {
+                    try {
+                        wait(remainingWaitTimeMs);
+                    } catch (InterruptedException ex) {
+                        // ignore.
+                    }
+                    remainingWaitTimeMs = mTimeoutMs - (System.currentTimeMillis() - startTimeMs);
+                } while (remainingWaitTimeMs > 0);
+
+                if (mWatchdogStop) {
+                    break;
+                }
+
+                if (!mWatchdogPinged) {
+                    fail("Action " + mAction + " Param " + mParam
+                            + " waited over " + (mTimeoutMs - remainingWaitTimeMs) + " ms");
+                    return;
+                }
+                mWatchdogPinged = false;
+            }
+        }
+
+        public synchronized void ping() {
+            mWatchdogPinged = true;
+            this.notify();
+        }
+
+        public synchronized void end() {
+            mWatchdogStop = true;
+            this.notify();
+        }
+    }
+
+    public MediaRandomTest() {
+        super("com.android.cts.media", MediaStubActivity.class);
+    }
+
+    public void testmRecorderRandomAction() throws Exception {
+        try {
+            long seed = System.currentTimeMillis();
+            Log.v(TAG, "seed = " + seed);
+            Random r = new Random(seed);
+
+            mMediaServerDied = false;
+            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) {
+                        Log.e(TAG, "mediaserver process died");
+                        mMediaServerDied = true;
+                    }
+                }
+            });
+
+            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();
+            for (int i = 0; i < NUMBER_OF_RECORDER_RANDOM_ACTIONS; i++) {
+                watchdog.ping();
+                assertTrue(!mMediaServerDied);
+
+                mAction = (int)(r.nextInt(14));
+                mParam = (int)(r.nextInt(1000000));
+                try {
+                    switch (mAction) {
+                    case 0:
+                        mRecorder.setAudioSource(mParam % 3);
+                        break;
+                    case 1:
+                        // XXX:
+                        // Fix gralloc source and change
+                        // mRecorder.setVideoSource(mParam % 3);
+                        mRecorder.setVideoSource(mParam % 2);
+                        break;
+                    case 2:
+                        mRecorder.setOutputFormat(mParam % 5);
+                        break;
+                    case 3:
+                        mRecorder.setAudioEncoder(mParam % 3);
+                        break;
+                    case 4:
+                        mRecorder.setVideoEncoder(mParam % 5);
+                        break;
+                    case 5:
+                        mRecorder.setPreviewDisplay(surfaceHolder.getSurface());
+                        break;
+                    case 6:
+                        int index = mParam % width.length;
+                        mRecorder.setVideoSize(width[index], height[index]);
+                        break;
+                    case 7:
+                        mRecorder.setVideoFrameRate(mParam % 40 - 5);
+                        break;
+                    case 8:
+                        mRecorder.setOutputFile(OUTPUT_FILE);
+                        break;
+                    case 9:
+                        mRecorder.prepare();
+                        break;
+                    case 10:
+                        mRecorder.start();
+                        break;
+                    case 11:
+                        Thread.sleep(mParam % 20);
+                        break;
+                    case 12:
+                        mRecorder.stop();
+                        break;
+                    case 13:
+                        mRecorder.reset();
+                        break;
+                    default:
+                        break;
+                    }
+                } catch (Exception e) {
+                }
+            }
+            watchdog.end();
+            watchdog.join();
+        } catch (Exception e) {
+            Log.v(TAG, e.toString());
+        }
+    }
+}