/*
 * Copyright (C) 2011 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.mediastress.cts;

import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Handler;
import android.os.Looper;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
import android.view.SurfaceHolder;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {

    private static String TAG = "MediaRecorderStressTest";
    private static final int NUMBER_OF_CAMERA_STRESS_LOOPS = 50;
    private static final int NUMBER_OF_RECORDER_STRESS_LOOPS = 50;
    private static final int NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS = 50;
    private static final int NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER = 50;
    private static final long WAIT_TIME_CAMERA_TEST = 3000;  // in ms
    private static final long WAIT_TIME_RECORDER_TEST = 5000;  // in ms
    private static final String OUTPUT_FILE = "/sdcard/temp";
    private static final String OUTPUT_FILE_EXT = ".3gp";
    private static final String MEDIA_STRESS_OUTPUT =
        "/sdcard/mediaStressOutput.txt";
    private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
    private final RecorderErrorCallback mRecorderErrorCallback = new RecorderErrorCallback();
    private final static int WAIT_TIMEOUT = 10000;

    private MediaRecorder mRecorder;
    private Camera mCamera;
    private Thread mLooperThread;
    private Handler mHandler;

    public static int mCameraId;
    public static int mProfileQuality = CamcorderProfile.QUALITY_HIGH;
    public static CamcorderProfile profile =
                        CamcorderProfile.get(mCameraId, mProfileQuality);

    private int mIterations = 50;
    private int mVideoEncoder;
    private int mAudioEncoder;
    private int mFrameRate;
    private int mVideoWidth;
    private int mVideoHeight;
    private int mBitRate;
    private boolean mRemoveVideo = true;
    private int mRecordDuration = 5000;

    public MediaRecorderStressTest() {
        super(MediaFrameworkTest.class);
    }

    protected void setUp() throws Exception {
        int cameraId = 0;
        CamcorderProfile profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_HIGH);
        mVideoEncoder = profile.videoCodec;
        mAudioEncoder = profile.audioCodec;
        mFrameRate = profile.videoFrameRate;
        mVideoWidth = profile.videoFrameWidth;
        mVideoHeight = profile.videoFrameHeight;
        mBitRate = profile.videoBitRate;

        final Semaphore sem = new Semaphore(0);
        mLooperThread = new Thread() {
            @Override
            public void run() {
                Log.v(TAG, "starting looper");
                Looper.prepare();
                mHandler = new Handler();
                sem.release();
                Looper.loop();
                Log.v(TAG, "quit looper");
            }
        };
        mLooperThread.start();
        if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
            fail("Failed to start the looper.");
        }

        getActivity();
        super.setUp();
    }

    @Override
    protected void tearDown() throws Exception {
        if (mHandler != null) {
            mHandler.getLooper().quit();
            mHandler = null;
        }
        if (mLooperThread != null) {
            mLooperThread.join(WAIT_TIMEOUT);
            if (mLooperThread.isAlive()) {
                fail("Failed to stop the looper.");
            }
            mLooperThread = null;
        }

        super.tearDown();
    }

    private void runOnLooper(final Runnable command) throws InterruptedException {
        final Semaphore sem = new Semaphore(0);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    command.run();
                } finally {
                    sem.release();
                }
            }
        });
        if (! sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
            fail("Failed to run the command on the looper.");
        }
    }

    private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
        public void onError(int error, android.hardware.Camera camera) {
            assertTrue("Camera test mediaserver died", error != android.hardware.Camera.CAMERA_ERROR_SERVER_DIED);
        }
    }

    private final class RecorderErrorCallback implements MediaRecorder.OnErrorListener {
        public void onError(MediaRecorder mr, int what, int extra) {
            // fail the test case no matter what error come up
            fail("mediaRecorder error");
        }
    }

    //Test case for stressing the camera preview.
    @LargeTest
    public void testStressCamera() throws Exception {
        SurfaceHolder mSurfaceHolder;
        mSurfaceHolder = MediaFrameworkTest.getSurfaceView().getHolder();
        File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
        Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
        output.write("Camera start preview stress:\n");
        output.write("Total number of loops:" +
                NUMBER_OF_CAMERA_STRESS_LOOPS + "\n");

        Log.v(TAG, "Start preview");
        output.write("No of loop: ");

        for (int i = 0; i< NUMBER_OF_CAMERA_STRESS_LOOPS; i++) {
            runOnLooper(new Runnable() {
                @Override
                public void run() {
                    mCamera = Camera.open();
                }
            });
            mCamera.setErrorCallback(mCameraErrorCallback);
            mCamera.setPreviewDisplay(mSurfaceHolder);
            mCamera.startPreview();
            Thread.sleep(WAIT_TIME_CAMERA_TEST);
            mCamera.stopPreview();
            mCamera.release();
            output.write(" ," + i);
        }

        output.write("\n\n");
        output.close();
    }

    //Test case for stressing the camera preview.
    @LargeTest
    public void testStressRecorder() throws Exception {
        String filename;
        SurfaceHolder mSurfaceHolder;
        mSurfaceHolder = MediaFrameworkTest.getSurfaceView().getHolder();
        File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
        Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
        output.write("H263 video record- reset after prepare Stress test\n");
        output.write("Total number of loops:" +
                NUMBER_OF_RECORDER_STRESS_LOOPS + "\n");

        output.write("No of loop: ");
        Log.v(TAG, "Start preview");
        for (int i = 0; i < NUMBER_OF_RECORDER_STRESS_LOOPS; i++) {
            runOnLooper(new Runnable() {
                @Override
                public void run() {
                    mRecorder = new MediaRecorder();
                }
            });
            Log.v(TAG, "counter = " + i);
            filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
            Log.v(TAG, filename);
            mRecorder.setOnErrorListener(mRecorderErrorCallback);
            mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mRecorder.setOutputFile(filename);
            mRecorder.setVideoFrameRate(mFrameRate);
            mRecorder.setVideoSize(176,144);
            Log.v(TAG, "setEncoder");
            mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
            mSurfaceHolder = MediaFrameworkTest.getSurfaceView().getHolder();
            Log.v(TAG, "setPreview");
            mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
            Log.v(TAG, "prepare");
            mRecorder.prepare();
            Log.v(TAG, "before release");
            Thread.sleep(WAIT_TIME_RECORDER_TEST);
            mRecorder.reset();
            mRecorder.release();
            output.write(", " + i);
        }

        output.write("\n\n");
        output.close();
    }

    //Stress test case for switching camera and video recorder preview.
    @LargeTest
    public void testStressCameraSwitchRecorder() throws Exception {
        String filename;
        SurfaceHolder mSurfaceHolder;
        mSurfaceHolder = MediaFrameworkTest.getSurfaceView().getHolder();
        File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
        Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
        output.write("Camera and video recorder preview switching\n");
        output.write("Total number of loops:"
                + NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER + "\n");

        Log.v(TAG, "Start preview");
        output.write("No of loop: ");
        for (int i = 0; i < NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER; i++) {
            runOnLooper(new Runnable() {
                @Override
                public void run() {
                    mCamera = Camera.open();
                }
            });
            mCamera.setErrorCallback(mCameraErrorCallback);
            mCamera.setPreviewDisplay(mSurfaceHolder);
            mCamera.startPreview();
            Thread.sleep(WAIT_TIME_CAMERA_TEST);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
            Log.v(TAG, "release camera");
            filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
            Log.v(TAG, filename);
            runOnLooper(new Runnable() {
                @Override
                public void run() {
                    mRecorder = new MediaRecorder();
                }
            });
            mRecorder.setOnErrorListener(mRecorderErrorCallback);
            mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mRecorder.setOutputFile(filename);
            mRecorder.setVideoFrameRate(mFrameRate);
            mRecorder.setVideoSize(176,144);
            Log.v(TAG, "Media recorder setEncoder");
            mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
            Log.v(TAG, "mediaRecorder setPreview");
            mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
            Log.v(TAG, "prepare");
            mRecorder.prepare();
            Log.v(TAG, "before release");
            Thread.sleep(WAIT_TIME_CAMERA_TEST);
            mRecorder.release();
            Log.v(TAG, "release video recorder");
            output.write(", " + i);
        }

        output.write("\n\n");
        output.close();
    }

    public void validateRecordedVideo(String recordedFile) throws Exception {
        MediaPlayer mp = new MediaPlayer();
        mp.setDataSource(recordedFile);
        mp.prepare();
        int duration = mp.getDuration();
        if (duration <= 0){
            assertTrue("stressRecordAndPlayback", false);
        }
        mp.release();
    }

    public void removeRecodedVideo(String filename){
        File video = new File(filename);
        Log.v(TAG, "remove recorded video " + filename);
        video.delete();
    }

    //Stress test case for record a video and play right away.
    @LargeTest
    public void testStressRecordVideoAndPlayback() throws Exception {
        String filename;
        SurfaceHolder mSurfaceHolder;
        mSurfaceHolder = MediaFrameworkTest.getSurfaceView().getHolder();
        File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
        Writer output = new BufferedWriter(
                new FileWriter(stressOutFile, true));
        output.write("Video record and play back stress test:\n");
        output.write("Total number of loops:"
                + NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS + "\n");

        output.write("No of loop: ");
        for (int i = 0; i < mIterations; i++){
            filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
            Log.v(TAG, filename);
            runOnLooper(new Runnable() {
                @Override
                public void run() {
                    mRecorder = new MediaRecorder();
                }
            });
            Log.v(TAG, "iterations : " + mIterations);
            Log.v(TAG, "videoEncoder : " + mVideoEncoder);
            Log.v(TAG, "audioEncoder : " + mAudioEncoder);
            Log.v(TAG, "frameRate : " + mFrameRate);
            Log.v(TAG, "videoWidth : " + mVideoWidth);
            Log.v(TAG, "videoHeight : " + mVideoHeight);
            Log.v(TAG, "bitRate : " + mBitRate);
            Log.v(TAG, "recordDuration : " + mRecordDuration);

            mRecorder.setOnErrorListener(mRecorderErrorCallback);
            mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mRecorder.setOutputFile(filename);
            mRecorder.setVideoFrameRate(mFrameRate);
            mRecorder.setVideoSize(mVideoWidth, mVideoHeight);
            mRecorder.setVideoEncoder(mVideoEncoder);
            mRecorder.setAudioEncoder(mAudioEncoder);
            Log.v(TAG, "mediaRecorder setPreview");
            mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
            mRecorder.prepare();
            mRecorder.start();
            Thread.sleep(mRecordDuration);
            Log.v(TAG, "Before stop");
            mRecorder.stop();
            mRecorder.release();
            //start the playback
            MediaPlayer mp = new MediaPlayer();
            mp.setDataSource(filename);
            mp.setDisplay(MediaFrameworkTest.getSurfaceView().getHolder());
            mp.prepare();
            mp.start();
            Thread.sleep(mRecordDuration);
            mp.release();
            validateRecordedVideo(filename);
            if (mRemoveVideo) {
                removeRecodedVideo(filename);
            }
            output.write(", " + i);
        }

        output.write("\n\n");
        output.close();
    }
}
