/*
 * Copyright (C) 2013 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.cts.verifier.camera.video;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Size;
import android.media.CamcorderProfile;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.VideoView;

import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.TreeSet;


/**
 * Tests for manual verification of camera video capture
 */
public class CameraVideoActivity extends PassFailButtons.Activity
        implements TextureView.SurfaceTextureListener {

    private static final String TAG = "CtsCameraVideo";
    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
    private static final int MEDIA_TYPE_IMAGE = 1;
    private static final int MEDIA_TYPE_VIDEO = 2;
    private static final int VIDEO_LENGTH = 3000; // in ms

    private TextureView mPreviewView;
    private SurfaceTexture mPreviewTexture;
    private int mPreviewTexWidth;
    private int mPreviewTexHeight;
    private int mPreviewRotation;
    private int mVideoRotation;

    private VideoView mPlaybackView;

    private Spinner mCameraSpinner;
    private Spinner mResolutionSpinner;

    private int mCurrentCameraId = -1;
    private Camera mCamera;

    private MediaRecorder mMediaRecorder;

    private List<Size> mPreviewSizes;
    private Size mNextPreviewSize;
    private Size mPreviewSize;
    private List<Integer> mVideoSizeIds;
    private int mCurrentVideoSizeId;

    private boolean isRecording = false;
    private boolean isPlayingBack = false;
    private Button captureButton;
    private ImageButton mPassButton;
    private ImageButton mFailButton;

    private TextView mStatusLabel;

    private TreeSet<String> mTestedCombinations = new TreeSet<String>();
    private TreeSet<String> mUntestedCombinations = new TreeSet<String>();

    private File outputVideoFile;

    /**
     * @see #MEDIA_TYPE_IMAGE
     * @see #MEDIA_TYPE_VIDEO
     */
    private static File getOutputMediaFile(int type) {
        // Question: why do I need to comment this to get it working?
        // Logcat says "external storage not ready"
        // if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) {
        //     Log.e(TAG, "external storage not ready");
        //     return null;
        // }

        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_MOVIES), TAG);

        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                Log.d(TAG, "failed to create directory");
                return null;
            }
        }

        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                    "IMG_" + timeStamp + ".jpg");
        } else if (type == MEDIA_TYPE_VIDEO) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                    "VID_" + timeStamp + ".mp4");
            if (VERBOSE) {
                Log.v(TAG, "getOutputMediaFile: output file " + mediaFile.getPath());
            }
        } else {
            return null;
        }

        return mediaFile;
    }

    private boolean prepareVideoRecorder() {

        mMediaRecorder = new MediaRecorder();

        // Step 1: unlock and set camera to MediaRecorder
        mCamera.unlock();
        mMediaRecorder.setCamera(mCamera);

        // Step 2: set sources
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        // Step 3: set a CamcorderProfile
        mMediaRecorder.setProfile(CamcorderProfile.get(mCurrentCameraId, mCurrentVideoSizeId));

        // Step 4: set output file
        outputVideoFile = getOutputMediaFile(MEDIA_TYPE_VIDEO);
        mMediaRecorder.setOutputFile(outputVideoFile.toString());

        // Step 5: set preview output
        // This is not necessary since preview has been taken care of

        // Step 6: set orientation hint
        mMediaRecorder.setOrientationHint(mVideoRotation);

        // Step 7: prepare configured MediaRecorder
        try {
            mMediaRecorder.prepare();
        } catch (IOException e) {
            Log.e(TAG, "IOException preparing MediaRecorder: ", e);
            releaseMediaRecorder();
            throw new AssertionError(e);
        }

        mMediaRecorder.setOnErrorListener(
                new MediaRecorder.OnErrorListener() {
                    @Override
                    public void onError(MediaRecorder mr, int what, int extra) {
                        if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
                            Log.e(TAG, "unknown error in media recorder, error: " + extra);
                        } else {
                            Log.e(TAG, "media recorder server died, error: " + extra);
                        }

                        failTest("Media recorder error.");
                    }
                });

        if (VERBOSE) {
            Log.v(TAG, "prepareVideoRecorder: prepared configured MediaRecorder");
        }

        return true;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.camera_video);
        setPassFailButtonClickListeners();
        setInfoResources(R.string.camera_video, R.string.video_info, /*viewId*/-1);

        mPreviewView = (TextureView) findViewById(R.id.video_capture);
        mPlaybackView = (VideoView) findViewById(R.id.video_playback);
        mPlaybackView.setOnCompletionListener(mPlaybackViewListener);

        captureButton = (Button) findViewById(R.id.record_button);
        mPassButton = (ImageButton) findViewById(R.id.pass_button);
        mFailButton = (ImageButton) findViewById(R.id.fail_button);
        mPassButton.setEnabled(false);
        mFailButton.setEnabled(true);

        mPreviewView.setSurfaceTextureListener(this);

        int numCameras = Camera.getNumberOfCameras();
        String[] cameraNames = new String[numCameras];
        for (int i = 0; i < numCameras; i++) {
            cameraNames[i] = "Camera " + i;
            mUntestedCombinations.add("All combinations for Camera " + i + "\n");
        }
        if (VERBOSE) {
            Log.v(TAG, "onCreate: number of cameras=" + numCameras);
        }
        mCameraSpinner = (Spinner) findViewById(R.id.cameras_selection);
        mCameraSpinner.setAdapter(
            new ArrayAdapter<String>(
                this, R.layout.cf_format_list_item, cameraNames));
        mCameraSpinner.setOnItemSelectedListener(mCameraSpinnerListener);

        mResolutionSpinner = (Spinner) findViewById(R.id.resolution_selection);
        mResolutionSpinner.setOnItemSelectedListener(mResolutionSelectedListener);

        mStatusLabel = (TextView) findViewById(R.id.status_label);
    }

    @Override
    public void onResume() {
        super.onResume();

        setUpCamera(mCameraSpinner.getSelectedItemPosition());
        if (VERBOSE) {
            Log.v(TAG, "onResume: camera has been setup");
        }

        setUpCaptureButton();
        if (VERBOSE) {
            Log.v(TAG, "onResume: captureButton has been setup");
        }

    }

    @Override
    public void onPause() {
        super.onPause();

        releaseMediaRecorder();
        shutdownCamera();
        mPreviewTexture = null;
    }

    private MediaPlayer.OnCompletionListener mPlaybackViewListener =
            new MediaPlayer.OnCompletionListener() {

                @Override
                public void onCompletion(MediaPlayer mp) {
                    isPlayingBack = false;
                    mPlaybackView.stopPlayback();
                    captureButton.setEnabled(true);
                    mStatusLabel.setText(getResources().getString(R.string.status_ready));
                }

    };

    private void releaseMediaRecorder() {
        if (mMediaRecorder != null) {
            mMediaRecorder.reset();
            mMediaRecorder.release();
            mMediaRecorder = null;
            mCamera.lock(); // check here, lock camera for later use
        }
    }

    @Override
    public String getTestDetails() {
        StringBuilder reportBuilder = new StringBuilder();
        reportBuilder.append("Tested combinations:\n");
        for (String combination : mTestedCombinations) {
            reportBuilder.append(combination);
        }
        reportBuilder.append("Untested combinations:\n");
        for (String combination : mUntestedCombinations) {
            reportBuilder.append(combination);
        }
        return reportBuilder.toString();
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface,
            int width, int height) {
        mPreviewTexture = surface;
        mPreviewTexWidth = width;
        mPreviewTexHeight = height;
        if (mCamera != null) {
            startPreview();
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        // Ignored, Camera does all the work for us
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return true;
    }


    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        // Invoked every time there's a new Camera preview frame
    }

    private AdapterView.OnItemSelectedListener mCameraSpinnerListener =
            new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
                    if (mCurrentCameraId != pos) {
                        setUpCamera(pos);
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    // Intentionally left blank
                }

            };

    private AdapterView.OnItemSelectedListener mResolutionSelectedListener =
            new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent,
                        View view, int position, long id) {
                    if (mVideoSizeIds.get(position) != mCurrentVideoSizeId) {
                        mCurrentVideoSizeId = mVideoSizeIds.get(position);
                        if (VERBOSE) {
                            Log.v(TAG, "onItemSelected: mCurrentVideoSizeId = " +
                                    mCurrentVideoSizeId);
                        }
                        mNextPreviewSize = matchPreviewRecordSize();
                        if (VERBOSE) {
                            Log.v(TAG, "onItemSelected: setting preview size "
                                    + mNextPreviewSize.width + "x" + mNextPreviewSize.height);
                        }

                        startPreview();
                        if (VERBOSE) {
                            Log.v(TAG, "onItemSelected: started new preview");
                        }
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    // Intentionally left blank
                }

            };


    private void setUpCaptureButton() {
        captureButton.setOnClickListener (
                new View.OnClickListener() {
                    @Override
                    public void onClick(View V) {
                        if ((!isRecording) && (!isPlayingBack)) {
                            if (prepareVideoRecorder()) {
                                mMediaRecorder.start();
                                if (VERBOSE) {
                                    Log.v(TAG, "onClick: started mMediaRecorder");
                                }
                                isRecording = true;
                                captureButton.setEnabled(false);
                                mStatusLabel.setText(getResources()
                                        .getString(R.string.status_recording));
                            } else {
                                releaseMediaRecorder();
                                Log.e(TAG, "media recorder cannot be set up");
                                failTest("Unable to set up media recorder.");
                            }
                            Handler h = new Handler();
                            Runnable mDelayedPreview = new Runnable() {
                                @Override
                                public void run() {
                                    mMediaRecorder.stop();
                                    releaseMediaRecorder();

                                    mPlaybackView.setVideoPath(outputVideoFile.getPath());
                                    mPlaybackView.start();
                                    isRecording = false;
                                    isPlayingBack = true;
                                    mStatusLabel.setText(getResources()
                                            .getString(R.string.status_playback));
                                    String combination = "Camera " + mCurrentCameraId + ", " +
                                            mCurrentVideoSizeId + "\n";
                                    mUntestedCombinations.remove(combination);
                                    mTestedCombinations.add(combination);

                                    if (mUntestedCombinations.isEmpty()) {
                                        mPassButton.setEnabled(true);
                                        if (VERBOSE) {
                                            Log.v(TAG, "run: test success");
                                        }
                                    }
                                }
                            };
                            h.postDelayed(mDelayedPreview, VIDEO_LENGTH);
                        }

                    }
                }
        );
    }

    private class VideoSizeNamePair {
        private int sizeId;
        private String sizeName;

        public VideoSizeNamePair(int id, String name) {
            sizeId = id;
            sizeName = name;
        }

        public int getSizeId() {
            return sizeId;
        }

        public String getSizeName() {
            return sizeName;
        }
    }

    private ArrayList<VideoSizeNamePair> getVideoSizeNamePairs(int cameraId) {
        int[] qualityArray = {
                CamcorderProfile.QUALITY_LOW,
                CamcorderProfile.QUALITY_HIGH,
                CamcorderProfile.QUALITY_QCIF,
                CamcorderProfile.QUALITY_QVGA,
                CamcorderProfile.QUALITY_CIF,
                CamcorderProfile.QUALITY_480P,
                CamcorderProfile.QUALITY_720P,
                CamcorderProfile.QUALITY_1080P,
                CamcorderProfile.QUALITY_2160P
        };

        String[] nameArray = {
                "LOW",
                "HIGH",
                "QCIF",
                "QVGA",
                "CIF",
                "480P",
                "720P",
                "1080P",
                "2160P"
        };

        ArrayList<VideoSizeNamePair> availableSizes =
                new ArrayList<VideoSizeNamePair> ();

        for (int i = 0; i < qualityArray.length; i++) {
            if (CamcorderProfile.hasProfile(cameraId, qualityArray[i])) {
                VideoSizeNamePair pair = new VideoSizeNamePair(qualityArray[i], nameArray[i]);
                availableSizes.add(pair);
            }
        }
        return availableSizes;
    }

    static class ResolutionQuality {
        private int videoSizeId;
        private int width;
        private int height;

        public ResolutionQuality() {
            // intentionally left blank
        }
        public ResolutionQuality(int newSizeId, int newWidth, int newHeight) {
            videoSizeId = newSizeId;
            width = newWidth;
            height = newHeight;
        }
    }

    private Size findRecordSize(int cameraId) {
        int[] possibleQuality = {
                CamcorderProfile.QUALITY_LOW,
                CamcorderProfile.QUALITY_HIGH,
                CamcorderProfile.QUALITY_QCIF,
                CamcorderProfile.QUALITY_QVGA,
                CamcorderProfile.QUALITY_CIF,
                CamcorderProfile.QUALITY_480P,
                CamcorderProfile.QUALITY_720P,
                CamcorderProfile.QUALITY_1080P,
                CamcorderProfile.QUALITY_2160P
        };

        ArrayList<ResolutionQuality> qualityList = new ArrayList<ResolutionQuality>();
        for (int i = 0; i < possibleQuality.length; i++) {
            if (CamcorderProfile.hasProfile(cameraId, possibleQuality[i])) {
                CamcorderProfile profile = CamcorderProfile.get(cameraId, possibleQuality[i]);
                qualityList.add(new ResolutionQuality(possibleQuality[i],
                        profile.videoFrameWidth, profile.videoFrameHeight));
            }
        }

        Size recordSize = null;
        for (int i = 0; i < qualityList.size(); i++) {
            if (mCurrentVideoSizeId == qualityList.get(i).videoSizeId) {
                recordSize = mCamera.new Size(qualityList.get(i).width,
                        qualityList.get(i).height);
                break;
            }
        }

        if (recordSize == null) {
            Log.e(TAG, "findRecordSize: did not find a match");
            failTest("Cannot find video size");
        }
        return recordSize;
    }

    // Match preview size with current recording size mCurrentVideoSizeId
    private Size matchPreviewRecordSize() {
        Size recordSize = findRecordSize(mCurrentCameraId);

        Size matchedSize = null;
        // First try to find exact match in size
        for (int i = 0; i < mPreviewSizes.size(); i++) {
            if (mPreviewSizes.get(i).equals(recordSize)) {
                matchedSize = mCamera.new Size(recordSize.width, recordSize.height);
                break;
            }
        }
        // Second try to find same ratio in size
        if (matchedSize == null) {
            for (int i = mPreviewSizes.size() - 1; i >= 0; i--) {
                if (mPreviewSizes.get(i).width * recordSize.height ==
                        mPreviewSizes.get(i).height * recordSize.width) {
                    matchedSize = mCamera.new Size(mPreviewSizes.get(i).width,
                            mPreviewSizes.get(i).height);
                    break;
                }
            }
        }
        //Third try to find one with similar if not the same apect ratio
        if (matchedSize == null) {
            for (int i = mPreviewSizes.size() - 1; i >= 0; i--) {
                if (Math.abs((float)mPreviewSizes.get(i).width * recordSize.height /
                        mPreviewSizes.get(i).height / recordSize.width - 1) < 0.12) {
                    matchedSize = mCamera.new Size(mPreviewSizes.get(i).width,
                            mPreviewSizes.get(i).height);
                    break;
                }
            }
        }
        // Last resort, just use the first preview size
        if (matchedSize == null) {
            matchedSize = mCamera.new Size(mPreviewSizes.get(0).width,
                    mPreviewSizes.get(0).height);
        }

        if (VERBOSE) {
            Log.v(TAG, "matchPreviewRecordSize " + matchedSize.width + "x" + matchedSize.height);
        }

        return matchedSize;
    }

    private void setUpCamera(int id) {
        shutdownCamera();

        mCurrentCameraId = id;
        try {
            mCamera = Camera.open(id);
        }
        catch (Exception e) {
            Log.e(TAG, "camera is not available", e);
            failTest("camera not available" + e.getMessage());
            return;
        }

        Camera.Parameters p = mCamera.getParameters();
        if (VERBOSE) {
            Log.v(TAG, "setUpCamera: setUpCamera got camera parameters");
        }

        // Get preview resolutions
        List<Size> unsortedSizes = p.getSupportedPreviewSizes();

        class SizeCompare implements Comparator<Size> {
            @Override
            public int compare(Size lhs, Size rhs) {
                if (lhs.width < rhs.width) return -1;
                if (lhs.width > rhs.width) return 1;
                if (lhs.height < rhs.height) return -1;
                if (lhs.height > rhs.height) return 1;
                return 0;
            }
        };

        SizeCompare s = new SizeCompare();
        TreeSet<Size> sortedResolutions = new TreeSet<Size>(s);
        sortedResolutions.addAll(unsortedSizes);

        mPreviewSizes = new ArrayList<Size>(sortedResolutions);

        ArrayList<VideoSizeNamePair> availableVideoSizes = getVideoSizeNamePairs(id);
        String[] availableVideoSizeNames = new String[availableVideoSizes.size()];
        mVideoSizeIds = new ArrayList<Integer>();
        for (int i = 0; i < availableVideoSizes.size(); i++) {
            availableVideoSizeNames[i] = availableVideoSizes.get(i).getSizeName();
            mVideoSizeIds.add(availableVideoSizes.get(i).getSizeId());
        }

        mResolutionSpinner.setAdapter(
            new ArrayAdapter<String>(
                this, R.layout.cf_format_list_item, availableVideoSizeNames));

        // Update untested
        mUntestedCombinations.remove("All combinations for Camera " + id + "\n");
        for (int videoSizeId: mVideoSizeIds) {
            String combination = "Camera " + id + ", " + videoSizeId + "\n";
            if (!mTestedCombinations.contains(combination)) {
                mUntestedCombinations.add(combination);
            }
        }

        // Set initial values
        mCurrentVideoSizeId = mVideoSizeIds.get(0);
        mNextPreviewSize = matchPreviewRecordSize();
        mResolutionSpinner.setSelection(0);

        // Set up correct display orientation
        CameraInfo info = new CameraInfo();
        Camera.getCameraInfo(id, info);
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0: degrees = 0; break;
            case Surface.ROTATION_90: degrees = 90; break;
            case Surface.ROTATION_180: degrees = 180; break;
            case Surface.ROTATION_270: degrees = 270; break;
        }

        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            mVideoRotation = (info.orientation + degrees) % 360;
            mPreviewRotation = (360 - mVideoRotation) % 360;  // compensate the mirror
        } else {  // back-facing
            mVideoRotation = (info.orientation - degrees + 360) % 360;
            mPreviewRotation = mVideoRotation;
        }
        if (mPreviewRotation != 0 && mPreviewRotation != 180) {
            Log.w(TAG,
                "Display orientation correction is not 0 or 180, as expected!");
        }

        mCamera.setDisplayOrientation(mPreviewRotation);

        // Start up preview if display is ready
        if (mPreviewTexture != null) {
            startPreview();
        }
    }

    private void shutdownCamera() {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * starts capturing and drawing frames on screen
     */
    private void startPreview() {

        mCamera.stopPreview();

        Matrix transform = new Matrix();
        float widthRatio = mNextPreviewSize.width / (float)mPreviewTexWidth;
        float heightRatio = mNextPreviewSize.height / (float)mPreviewTexHeight;
        if (VERBOSE) {
            Log.v(TAG, "startPreview: widthRatio=" + widthRatio + " " + "heightRatio=" +
                    heightRatio);
        }

        if (heightRatio < widthRatio) {
            transform.setScale(1, heightRatio / widthRatio);
            transform.postTranslate(0,
                    mPreviewTexHeight * (1 - heightRatio / widthRatio) / 2);
            if (VERBOSE) {
                Log.v(TAG, "startPreview: shrink vertical by " + heightRatio / widthRatio);
            }
        } else {
            transform.setScale(widthRatio / heightRatio, 1);
            transform.postTranslate(mPreviewTexWidth * (1 - widthRatio / heightRatio) / 2, 0);
            if (VERBOSE) {
                Log.v(TAG, "startPreview: shrink horizontal by " + widthRatio / heightRatio);
            }
        }

        mPreviewView.setTransform(transform);

        mPreviewSize = mNextPreviewSize;

        Camera.Parameters p = mCamera.getParameters();
        p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        mCamera.setParameters(p);

        try {
            mCamera.setPreviewTexture(mPreviewTexture);
            if (mPreviewTexture == null) {
                Log.e(TAG, "preview texture is null.");
            }
            if (VERBOSE) {
                Log.v(TAG, "startPreview: set preview texture in startPreview");
            }
            mCamera.startPreview();
            if (VERBOSE) {
                Log.v(TAG, "startPreview: started preview in startPreview");
            }
        } catch (IOException ioe) {
            Log.e(TAG, "Unable to start up preview", ioe);
            // Show a dialog box to tell user test failed
            failTest("Unable to start preview.");
        }
    }

    private void failTest(String failMessage) {
        DialogInterface.OnClickListener dialogClickListener =
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                            case DialogInterface.BUTTON_POSITIVE:
                                setTestResultAndFinish(/* passed */false);
                                break;
                            case DialogInterface.BUTTON_NEGATIVE:
                                break;
                        }
                    }
                };

        AlertDialog.Builder builder = new AlertDialog.Builder(CameraVideoActivity.this);
        builder.setMessage(getString(R.string.dialog_fail_test) + ". " + failMessage)
                .setPositiveButton(R.string.fail_quit, dialogClickListener)
                .setNegativeButton(R.string.cancel, dialogClickListener)
                .show();
    }

}
