Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1c5d4fa authored by Eino-Ville Talvala's avatar Eino-Ville Talvala Committed by Android (Google) Code Review
Browse files

Merge "Add a sound-playing method to Camera API." into ics-mr1

parents 785fd368 e0cc55ac
Loading
Loading
Loading
Loading
+206 −3
Original line number Diff line number Diff line
@@ -22,9 +22,12 @@ import android.graphics.ImageFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemProperties;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
@@ -154,6 +157,7 @@ public class Camera {
    private boolean mOneShot;
    private boolean mWithBuffer;
    private boolean mFaceDetectionRunning = false;
    private boolean mReleased = false;

    /**
     * Broadcast Action:  A new picture is taken by the camera, and the entry of
@@ -303,7 +307,7 @@ public class Camera {
    }

    protected void finalize() {
        native_release();
        release();
    }

    private native final void native_setup(Object camera_this, int cameraId);
@@ -318,6 +322,15 @@ public class Camera {
    public final void release() {
        native_release();
        mFaceDetectionRunning = false;
        if (mCameraSoundPlayers != null) {
            for (CameraSoundPlayer csp: mCameraSoundPlayers) {
                if (csp != null) {
                    csp.release();
                }
            }
            mCameraSoundPlayers = null;
        }
        mReleased = true;
    }

    /**
@@ -3452,4 +3465,194 @@ public class Camera {
            return result;
        }
    };

    /**
     * <p>The set of default system sounds for camera actions. Use this with
     * {@link #playSound} to play an appropriate sound when implementing a
     * custom still or video recording mechanism through the preview
     * callbacks.</p>
     *
     * <p>There is no need to play sounds when using {@link #takePicture} or
     * {@link android.media.MediaRecorder} for still images or video,
     * respectively, as these play their own sounds when needed.</p>
     *
     * @see #playSound
     * @hide
     */
    public static class Sound {
        /**
         * The sound used by {@link android.hardware.Camera#takePicture} to
         * indicate still image capture.
         */
        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 Camera class.
         */
        public static final int FOCUS_COMPLETE        = 1;

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

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

        private static final int NUM_SOUNDS           = 4;
    };

    /**
     * <p>Play one of the predefined platform sounds for camera actions.</p>
     *
     * <p>Use this method to play a platform-specific sound for various camera
     * actions. The sound playing is done asynchronously, with the same behavior
     * and content as the sounds played by {@link #takePicture takePicture},
     * {@link android.media.MediaRecorder#start MediaRecorder.start}, and
     * {@link android.media.MediaRecorder#stop MediaRecorder.stop}.</p>
     *
     * <p>Using this method makes it easy to match the default device sounds
     * when recording or capturing data through the preview callbacks
     * ({@link #setPreviewCallback setPreviewCallback},
     * {@link #setPreviewTexture setPreviewTexture}).</p>
     *
     * @param soundId The type of sound to play, selected from the options in
     *   {@link android.hardware.Camera.Sound}
     * @see android.hardware.Camera.Sound
     * @see #takePicture
     * @see android.media.MediaRecorder
     * @hide
     */
    public void playSound(int soundId) {
        if (mReleased) return;
        if (mCameraSoundPlayers == null) {
            mCameraSoundPlayers = new CameraSoundPlayer[Sound.NUM_SOUNDS];
        }
        if (mCameraSoundPlayers[soundId] == null) {
            mCameraSoundPlayers[soundId] = new CameraSoundPlayer(soundId);
        }
        mCameraSoundPlayers[soundId].play();
    }

    private CameraSoundPlayer[] mCameraSoundPlayers;

    private static class CameraSoundPlayer implements Runnable {
        private int mSoundId;
        private int mAudioStreamType;
        private MediaPlayer mPlayer;
        private Thread mThread;
        private boolean mExit;
        private int mPlayCount;

        private static final String mShutterSound    =
                "/system/media/audio/ui/camera_click.ogg";
        private static final String mFocusSound      =
                "/system/media/audio/ui/camera_focus.ogg";
        private static final String mVideoStartSound =
                "/system/media/audio/ui/VideoRecord.ogg";
        private static final String mVideoStopSound  =
                "/system/media/audio/ui/VideoRecord.ogg";

        @Override
        public void run() {
            String soundFilePath;
            switch (mSoundId) {
                case Sound.SHUTTER_CLICK:
                    soundFilePath = mShutterSound;
                    break;
                case Sound.FOCUS_COMPLETE:
                    soundFilePath = mFocusSound;
                    break;
                case Sound.START_VIDEO_RECORDING:
                    soundFilePath = mVideoStartSound;
                    break;
                case Sound.STOP_VIDEO_RECORDING:
                    soundFilePath = mVideoStopSound;
                    break;
                default:
                    Log.e(TAG, "Unknown sound " + mSoundId + " requested.");
                    return;
            }
            mPlayer = new MediaPlayer();
            try {
                mPlayer.setAudioStreamType(mAudioStreamType);
                mPlayer.setDataSource(soundFilePath);
                mPlayer.setLooping(false);
                mPlayer.prepare();
            } catch(IOException e) {
                Log.e(TAG, "Error setting up sound " + mSoundId, e);
                return;
            }

            while(true) {
                try {
                    synchronized (this) {
                        while(true) {
                            if (mExit) {
                                return;
                            } else if (mPlayCount <= 0) {
                                wait();
                            } else {
                                mPlayCount--;
                                break;
                            }
                        }
                    }
                    mPlayer.start();
                } catch (Exception e) {
                    Log.e(TAG, "Error playing sound " + mSoundId, e);
                }
            }
        }

        public CameraSoundPlayer(int soundId) {
            mSoundId = soundId;
            if (SystemProperties.get("ro.camera.sound.forced", "0").equals("0")) {
                mAudioStreamType = AudioManager.STREAM_MUSIC;
            } else {
                mAudioStreamType = AudioManager.STREAM_SYSTEM_ENFORCED;
            }
        }

        public void play() {
            if (mThread == null) {
                mThread = new Thread(this);
                mThread.start();
            }
            synchronized (this) {
                mPlayCount++;
                notifyAll();
            }
        }

        public void release() {
            if (mThread != null) {
                synchronized (this) {
                    mExit = true;
                    notifyAll();
                }
                try {
                    mThread.join();
                } catch (InterruptedException e) {
                }
                mThread = null;
            }
            if (mPlayer != null) {
                mPlayer.release();
                mPlayer = null;
            }
        }

        @Override
        protected void finalize() {
            release();
        }
    }

}
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ PRODUCT_COPY_FILES += \
	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
	$(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ PRODUCT_COPY_FILES += \
	$(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
	$(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
	$(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
	$(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ PRODUCT_COPY_FILES += \
	$(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
	$(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
	$(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
	$(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
+9.16 KiB

File added.

No diff preview for this file type.