diff options
-rw-r--r-- | src/com/android/camera/CaptureModule.java | 99 | ||||
-rw-r--r-- | src/com/android/camera/CaptureUI.java | 4 |
2 files changed, 97 insertions, 6 deletions
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index f1c95471b..c45496c1f 100644 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -94,6 +94,7 @@ import com.android.camera.util.CameraUtil; import com.android.camera.util.PersistUtil; import com.android.camera.util.SettingTranslation; import com.android.camera.util.ApiHelper; +import com.android.camera.util.AccessibilityUtils; import com.android.internal.util.MemInfoReader; import org.codeaurora.snapcam.R; @@ -115,7 +116,7 @@ public class CaptureModule implements CameraModule, PhotoController, MediaSaveService.Listener, ClearSightImageProcessor.Callback, SettingsManager.Listener, LocationManager.Listener, CountDownView.OnCountDownFinishedListener, - MediaRecorder.OnInfoListener{ + MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener { public static final int DUAL_MODE = 0; public static final int BAYER_MODE = 1; public static final int MONO_MODE = 2; @@ -230,6 +231,7 @@ public class CaptureModule implements CameraModule, PhotoController, private int mDisplayOrientation; private boolean mIsRefocus = false; private int mChosenImageFormat; + private Toast mToast; /** * A {@link CameraCaptureSession } for camera preview. @@ -1879,6 +1881,7 @@ public class CaptureModule implements CameraModule, PhotoController, @Override public void onPauseBeforeSuper() { mPaused = true; + mToast = null; mUI.onPause(); if (mIsRecordingVideo) { stopRecordingVideo(getMainCameraId()); @@ -2889,14 +2892,30 @@ public class CaptureModule implements CameraModule, PhotoController, private void stopRecordingVideo(int cameraId) { Log.d(TAG, "stopRecordingVideo " + cameraId); + boolean shouldAddToMediaStoreNow = false; // Stop recording mFrameProcessor.setVideoOutputSurface(null); mFrameProcessor.onClose(); closePreviewSession(); - mMediaRecorder.stop(); - mMediaRecorder.reset(); - mMediaRecorder.setOnInfoListener(null); - saveVideo(); + try { + mMediaRecorder.setOnErrorListener(null); + mMediaRecorder.setOnInfoListener(null); + mMediaRecorder.stop(); + shouldAddToMediaStoreNow = true; + AccessibilityUtils.makeAnnouncement(mUI.getVideoButton(), + mActivity.getString(R.string.video_recording_stopped)); + } catch (RuntimeException e) { + Log.e(TAG, "MediaRecoder stop fail", e); + if (mVideoFilename != null) deleteVideoFile(mVideoFilename); + } + if (shouldAddToMediaStoreNow) { + saveVideo(); + } + + // release media recorder + releaseMediaRecorder(); + releaseAudioFocus(); + mUI.showRecordingUI(false, false); mUI.enableShutter(true); @@ -2993,6 +3012,9 @@ public class CaptureModule implements CameraModule, PhotoController, if (mCaptureTimeLapse) { size = CameraSettings.getTimeLapseQualityFor(size); } + + if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder(); + updateHFRSetting(); boolean hfr = mHighSpeedCapture && !mHighSpeedRecordingMode; mProfile = CamcorderProfile.get(cameraId, size); @@ -3064,7 +3086,15 @@ public class CaptureModule implements CameraModule, PhotoController, } else { mMediaRecorder.setOrientationHint(rotation); } - mMediaRecorder.prepare(); + try { + mMediaRecorder.prepare(); + } catch (IOException e) { + Log.e(TAG, "prepare failed for " + mVideoFilename, e); + releaseMediaRecorder(); + throw new RuntimeException(e); + } + + mMediaRecorder.setOnErrorListener(this); mMediaRecorder.setOnInfoListener(this); } @@ -3911,6 +3941,18 @@ public class CaptureModule implements CameraModule, PhotoController, enableRecordingLocation(false); } + // from MediaRecorder.OnErrorListener + @Override + public void onError(MediaRecorder mr, int what, int extra) { + Log.e(TAG, "MediaRecorder error. what=" + what + ". extra=" + extra); + stopRecordingVideo(getMainCameraId()); + mUI.showUIafterRecording(); + if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { + // We may have run out of space on the sdcard. + mActivity.updateStorageSpaceAndHint(); + } + } + // from MediaRecorder.OnInfoListener @Override public void onInfo(MediaRecorder mr, int what, int extra) { @@ -3939,4 +3981,49 @@ public class CaptureModule implements CameraModule, PhotoController, Storage.setSaveSDCard(mSettingsManager.getValue(SettingsManager .KEY_CAMERA_SAVEPATH).equals("1")); } + + private void deleteVideoFile(String fileName) { + Log.v(TAG, "Deleting video " + fileName); + File f = new File(fileName); + if (!f.delete()) { + Log.v(TAG, "Could not delete " + fileName); + } + } + + private void releaseMediaRecorder() { + Log.v(TAG, "Releasing media recorder."); + if (mMediaRecorder != null) { + cleanupEmptyFile(); + mMediaRecorder.reset(); + mMediaRecorder.release(); + mMediaRecorder = null; + } + mVideoFilename = null; + } + + private void cleanupEmptyFile() { + if (mVideoFilename != null) { + File f = new File(mVideoFilename); + if (f.length() == 0 && f.delete()) { + Log.v(TAG, "Empty video file deleted: " + mVideoFilename); + mVideoFilename = null; + } + } + } + + private void releaseAudioFocus() { + AudioManager am = (AudioManager)mActivity.getSystemService(Context.AUDIO_SERVICE); + int result = am.abandonAudioFocus(null); + if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) { + Log.v(TAG, "Audio focus release failed"); + } + } + + private void showToast(String tips) { + if (mToast == null) { + mToast = Toast.makeText(mActivity, tips, Toast.LENGTH_LONG); + } + mToast.setText(tips); + mToast.show(); + } } diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java index d112f9d34..ed11807da 100644 --- a/src/com/android/camera/CaptureUI.java +++ b/src/com/android/camera/CaptureUI.java @@ -1383,4 +1383,8 @@ public class CaptureUI implements FocusOverlayManager.FocusUI, } } + + public ImageView getVideoButton() { + return mVideoButton; + } } |