/*
 * 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;

import android.media.AudioManager;
import android.media.SoundPool;
import android.util.Log;

/**
 * <p>A class for producing sounds that match those produced by various actions
 * taken by the media and camera APIs.  </p>
 *
 * <p>This class is recommended for use with the {@link android.hardware.camera2} API, since the
 * camera2 API does not play any sounds on its own for any capture or video recording actions.</p>
 *
 * <p>With the older {@link android.hardware.Camera} API, use this class to play an appropriate
 * camera operation sound when implementing a custom still or video recording mechanism (through the
 * Camera preview callbacks with
 * {@link android.hardware.Camera#setPreviewCallback Camera.setPreviewCallback}, or through GPU
 * processing with {@link android.hardware.Camera#setPreviewTexture Camera.setPreviewTexture}, for
 * example), or when implementing some other camera-like function in your application.</p>
 *
 * <p>There is no need to play sounds when using
 * {@link android.hardware.Camera#takePicture Camera.takePicture} or
 * {@link android.media.MediaRecorder} for still images or video, respectively,
 * as the Android framework will play the appropriate sounds when needed for
 * these calls.</p>
 *
 */
public class MediaActionSound {
    private static final int NUM_MEDIA_SOUND_STREAMS = 1;

    private SoundPool mSoundPool;
    private SoundState[] mSounds;

    private static final String[] SOUND_DIRS = {
        "/product/media/audio/ui/",
        "/system/media/audio/ui/",
    };

    private static final String[] SOUND_FILES = {
        "camera_click.ogg",
        "camera_focus.ogg",
        "VideoRecord.ogg",
        "VideoStop.ogg"
    };

    private static final String TAG = "MediaActionSound";
    /**
     * The sound used by
     * {@link android.hardware.Camera#takePicture Camera.takePicture} to
     * indicate still image capture.
     * @see #play
     */
    public static final int SHUTTER_CLICK         = 0;

    /**
     * A sound to indicate that focusing has completed. Because deciding
     * when this occurs is application-dependent, this sound is not used by
     * any methods in the media or camera APIs.
     * @see #play
     */
    public static final int FOCUS_COMPLETE        = 1;

    /**
     * The sound used by
     * {@link android.media.MediaRecorder#start MediaRecorder.start()} to
     * indicate the start of video recording.
     * @see #play
     */
    public static final int START_VIDEO_RECORDING = 2;

    /**
     * The sound used by
     * {@link android.media.MediaRecorder#stop MediaRecorder.stop()} to
     * indicate the end of video recording.
     * @see #play
     */
    public static final int STOP_VIDEO_RECORDING  = 3;

    /**
     * States for SoundState.
     * STATE_NOT_LOADED             : sample not loaded
     * STATE_LOADING                : sample being loaded: waiting for load completion callback
     * STATE_LOADING_PLAY_REQUESTED : sample being loaded and playback request received
     * STATE_LOADED                 : sample loaded, ready for playback
     */
    private static final int STATE_NOT_LOADED             = 0;
    private static final int STATE_LOADING                = 1;
    private static final int STATE_LOADING_PLAY_REQUESTED = 2;
    private static final int STATE_LOADED                 = 3;

    private class SoundState {
        public final int name;
        public int id;
        public int state;

        public SoundState(int name) {
            this.name = name;
            id = 0; // 0 is an invalid sample ID.
            state = STATE_NOT_LOADED;
        }
    }
    /**
     * Construct a new MediaActionSound instance. Only a single instance is
     * needed for playing any platform media action sound; you do not need a
     * separate instance for each sound type.
     */
    public MediaActionSound() {
        mSoundPool = new SoundPool.Builder()
                .setMaxStreams(NUM_MEDIA_SOUND_STREAMS)
                .setAudioAttributes(new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
                    .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .build())
                .build();
        mSoundPool.setOnLoadCompleteListener(mLoadCompleteListener);
        mSounds = new SoundState[SOUND_FILES.length];
        for (int i = 0; i < mSounds.length; i++) {
            mSounds[i] = new SoundState(i);
        }
    }

    private int loadSound(SoundState sound) {
        final String soundFileName = SOUND_FILES[sound.name];
        for (String soundDir : SOUND_DIRS) {
            int id = mSoundPool.load(soundDir + soundFileName, 1);
            if (id > 0) {
                sound.state = STATE_LOADING;
                sound.id = id;
                return id;
            }
        }
        return 0;
    }

    /**
     * Preload a predefined platform sound to minimize latency when the sound is
     * played later by {@link #play}.
     * @param soundName The type of sound to preload, selected from
     *         SHUTTER_CLICK, FOCUS_COMPLETE, START_VIDEO_RECORDING, or
     *         STOP_VIDEO_RECORDING.
     * @see #play
     * @see #SHUTTER_CLICK
     * @see #FOCUS_COMPLETE
     * @see #START_VIDEO_RECORDING
     * @see #STOP_VIDEO_RECORDING
     */
    public void load(int soundName) {
        if (soundName < 0 || soundName >= SOUND_FILES.length) {
            throw new RuntimeException("Unknown sound requested: " + soundName);
        }
        SoundState sound = mSounds[soundName];
        synchronized (sound) {
            switch (sound.state) {
            case STATE_NOT_LOADED:
                if (loadSound(sound) <= 0) {
                    Log.e(TAG, "load() error loading sound: " + soundName);
                }
                break;
            default:
                Log.e(TAG, "load() called in wrong state: " + sound + " for sound: "+ soundName);
                break;
            }
        }
    }

    /**
     * <p>Play one of the predefined platform sounds for media actions.</p>
     *
     * <p>Use this method to play a platform-specific sound for various media
     * actions. The sound playback is done asynchronously, with the same
     * behavior and content as the sounds played by
     * {@link android.hardware.Camera#takePicture Camera.takePicture},
     * {@link android.media.MediaRecorder#start MediaRecorder.start}, and
     * {@link android.media.MediaRecorder#stop MediaRecorder.stop}.</p>
     *
     * <p>With the {@link android.hardware.camera2 camera2} API, this method can be used to play
     * standard camera operation sounds with the appropriate system behavior for such sounds.</p>

     * <p>With the older {@link android.hardware.Camera} API, using this method makes it easy to
     * match the default device sounds when recording or capturing data through the preview
     * callbacks, or when implementing custom camera-like features in your application.</p>
     *
     * <p>If the sound has not been loaded by {@link #load} before calling play,
     * play will load the sound at the cost of some additional latency before
     * sound playback begins. </p>
     *
     * @param soundName The type of sound to play, selected from
     *         SHUTTER_CLICK, FOCUS_COMPLETE, START_VIDEO_RECORDING, or
     *         STOP_VIDEO_RECORDING.
     * @see android.hardware.Camera#takePicture
     * @see android.media.MediaRecorder
     * @see #SHUTTER_CLICK
     * @see #FOCUS_COMPLETE
     * @see #START_VIDEO_RECORDING
     * @see #STOP_VIDEO_RECORDING
     */
    public void play(int soundName) {
        if (soundName < 0 || soundName >= SOUND_FILES.length) {
            throw new RuntimeException("Unknown sound requested: " + soundName);
        }
        SoundState sound = mSounds[soundName];
        synchronized (sound) {
            switch (sound.state) {
            case STATE_NOT_LOADED:
                loadSound(sound);
                if (loadSound(sound) <= 0) {
                    Log.e(TAG, "play() error loading sound: " + soundName);
                    break;
                }
                // FALL THROUGH

            case STATE_LOADING:
                sound.state = STATE_LOADING_PLAY_REQUESTED;
                break;
            case STATE_LOADED:
                mSoundPool.play(sound.id, 1.0f, 1.0f, 0, 0, 1.0f);
                break;
            default:
                Log.e(TAG, "play() called in wrong state: " + sound.state + " for sound: "+ soundName);
                break;
            }
        }
    }

    private SoundPool.OnLoadCompleteListener mLoadCompleteListener =
            new SoundPool.OnLoadCompleteListener() {
        public void onLoadComplete(SoundPool soundPool,
                int sampleId, int status) {
            for (SoundState sound : mSounds) {
                if (sound.id != sampleId) {
                    continue;
                }
                int playSoundId = 0;
                synchronized (sound) {
                    if (status != 0) {
                        sound.state = STATE_NOT_LOADED;
                        sound.id = 0;
                        Log.e(TAG, "OnLoadCompleteListener() error: " + status +
                                " loading sound: "+ sound.name);
                        return;
                    }
                    switch (sound.state) {
                    case STATE_LOADING:
                        sound.state = STATE_LOADED;
                        break;
                    case STATE_LOADING_PLAY_REQUESTED:
                        playSoundId = sound.id;
                        sound.state = STATE_LOADED;
                        break;
                    default:
                        Log.e(TAG, "OnLoadCompleteListener() called in wrong state: "
                                + sound.state + " for sound: "+ sound.name);
                        break;
                    }
                }
                if (playSoundId != 0) {
                    soundPool.play(playSoundId, 1.0f, 1.0f, 0, 0, 1.0f);
                }
                break;
            }
        }
    };

    /**
     * Free up all audio resources used by this MediaActionSound instance. Do
     * not call any other methods on a MediaActionSound instance after calling
     * release().
     */
    public void release() {
        if (mSoundPool != null) {
            for (SoundState sound : mSounds) {
                synchronized (sound) {
                    sound.state = STATE_NOT_LOADED;
                    sound.id = 0;
                }
            }
            mSoundPool.release();
            mSoundPool = null;
        }
    }
}
