Merge "Move Camera.Sound to a stand-alone class CameraSound." into ics-mr1

This commit is contained in:
Wu-cheng Li
2011-11-21 18:10:52 -08:00
committed by Android (Google) Code Review
2 changed files with 223 additions and 203 deletions

View File

@@ -22,12 +22,9 @@ 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;
@@ -157,7 +154,6 @@ 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
@@ -322,15 +318,6 @@ 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;
}
/**
@@ -3503,194 +3490,4 @@ public class Camera {
return false;
}
};
/**
* <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();
}
}
}

View File

@@ -0,0 +1,223 @@
/*
* 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.hardware;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.SystemProperties;
import android.util.Log;
import java.io.IOException;
/**
* <p>Use this class 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 #android.hardware.Camera#takePicture}
* or {@link android.media.MediaRecorder} for still images or video,
* respectively, as these play their own sounds when needed.</p>
*
* @hide
*/
public class CameraSound {
private static final String TAG = "CameraSound";
/**
* 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;
private CameraSoundPlayer[] mCameraSoundPlayers;
public CameraSound() {
}
/**
* <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.</p>
*
* @param soundId The type of sound to play, selected from SHUTTER_CLICK,
* FOCUS_COMPLETE, START_VIDEO_RECORDING, or STOP_VIDEO_RECORDING.
* @see android.hardware#takePicture
* @see android.media.MediaRecorder
* @see #SHUTTER_CLICK
* @see #FOCUS_COMPLETE
* @see #START_VIDEO_RECORDING
* @see #STOP_VIDEO_RECORDING
*/
public void playSound(int soundId) {
if (mCameraSoundPlayers == null) {
mCameraSoundPlayers = new CameraSoundPlayer[NUM_SOUNDS];
}
if (mCameraSoundPlayers[soundId] == null) {
mCameraSoundPlayers[soundId] = new CameraSoundPlayer(soundId);
}
mCameraSoundPlayers[soundId].play();
}
public void release() {
if (mCameraSoundPlayers != null) {
for (CameraSoundPlayer csp: mCameraSoundPlayers) {
if (csp != null) {
csp.release();
}
}
mCameraSoundPlayers = null;
}
}
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 SHUTTER_CLICK:
soundFilePath = mShutterSound;
break;
case FOCUS_COMPLETE:
soundFilePath = mFocusSound;
break;
case START_VIDEO_RECORDING:
soundFilePath = mVideoStartSound;
break;
case 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();
}
}
}