summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWu-cheng Li <wuchengli@google.com>2010-11-06 14:47:17 +0800
committerWu-cheng Li <wuchengli@google.com>2010-11-08 23:20:35 +0800
commite424c1b9176bb838feb67180a738836bb42b2a7a (patch)
tree9f3fb9f025586f78f105fab0948b8e0d2722b1b8
parent3ecd5f5a78f828a2333457d3ee1ff5e180134fe1 (diff)
downloadLegacyCamera-e424c1b9176bb838feb67180a738836bb42b2a7a.zip
LegacyCamera-e424c1b9176bb838feb67180a738836bb42b2a7a.tar.gz
LegacyCamera-e424c1b9176bb838feb67180a738836bb42b2a7a.tar.bz2
Set video orientation hint according to device orientation. do not merge
Also rotate the on-screen icons according to device orientation. Move prepare to startVideoRecording because we need to set the latest orientation to MediaRecorder.setOrientationHint. setOrientationHint has to be called before prepare. bug:3163671 Change-Id: I69efe7408aa5d47e2ef9bbab9dd4337a10d56814
-rw-r--r--src/com/android/camera/Camera.java13
-rw-r--r--src/com/android/camera/VideoCamera.java282
-rw-r--r--src/com/android/camera/ui/CamcorderHeadUpDisplay.java9
3 files changed, 157 insertions, 147 deletions
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 99951c3..8b4de05 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -1043,12 +1043,13 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// the camera then point the camera to floor or sky, we still have
// the correct orientation.
if (orientation == ORIENTATION_UNKNOWN) return;
- orientation = roundOrientation(orientation);
- if (orientation != mOrientation) {
- mOrientation = orientation;
- mOrientationCompensation = orientation
- + Util.getDisplayRotation(Camera.this);
-
+ mOrientation = roundOrientation(orientation);
+ // When the screen is unlocked, display rotation may change. Always
+ // calculate the up-to-date orientationCompensation.
+ int orientationCompensation = mOrientation
+ + Util.getDisplayRotation(Camera.this);
+ if (mOrientationCompensation != orientationCompensation) {
+ mOrientationCompensation = orientationCompensation;
if (!mIsImageCaptureIntent) {
setOrientationIndicator(mOrientationCompensation);
}
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index ae092f7..32b7bed 100644
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -35,6 +35,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
+import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.media.CamcorderProfile;
@@ -57,6 +58,7 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.OrientationEventListener;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
@@ -89,7 +91,6 @@ public class VideoCamera extends NoSearchActivity
private static final String TAG = "videocamera";
- private static final int INIT_RECORDER = 3;
private static final int CLEAR_SCREEN_DELAY = 4;
private static final int UPDATE_RECORD_TIME = 5;
private static final int ENABLE_SHUTTER_BUTTON = 6;
@@ -179,6 +180,12 @@ public class VideoCamera extends NoSearchActivity
private int mNumberOfCameras;
private int mCameraId;
+ private MyOrientationEventListener mOrientationListener;
+ // The device orientation in degrees. Default is unknown.
+ private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
+ // The orientation compensation for icons and thumbnails.
+ private int mOrientationCompensation = 0;
+
// This Handler is used to post message back onto the main thread of the
// application
private class MainHandler extends Handler {
@@ -201,11 +208,6 @@ public class VideoCamera extends NoSearchActivity
break;
}
- case INIT_RECORDER: {
- initializeRecorder();
- break;
- }
-
default:
Log.v(TAG, "Unhandled message: " + msg.what);
break;
@@ -224,7 +226,7 @@ public class VideoCamera extends NoSearchActivity
stopVideoRecording();
} else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
updateAndShowStorageHint(true);
- initializeRecorder();
+ updateThumbnailButton();
} else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
// SD card unavailable
// handled in ACTION_MEDIA_EJECT
@@ -365,6 +367,8 @@ public class VideoCamera extends NoSearchActivity
mShutterButton.setOnShutterButtonListener(this);
mShutterButton.requestFocus();
+ mOrientationListener = new MyOrientationEventListener(VideoCamera.this);
+
// Make sure preview is started.
try {
startPreviewThread.join();
@@ -407,10 +411,11 @@ public class VideoCamera extends NoSearchActivity
if (mIsVideoCaptureIntent) {
group = filterPreferenceScreenByIntent(group);
}
- mHeadUpDisplay.initialize(this, group);
+ mHeadUpDisplay.initialize(this, group, mOrientationCompensation);
}
private void attachHeadUpDisplay() {
+ mHeadUpDisplay.setOrientation(mOrientationCompensation);
FrameLayout frame = (FrameLayout) findViewById(R.id.frame);
mGLRootView = new GLRootView(this);
frame.addView(mGLRootView);
@@ -423,6 +428,47 @@ public class VideoCamera extends NoSearchActivity
mGLRootView = null;
}
+ public static int roundOrientation(int orientation) {
+ return ((orientation + 45) / 90 * 90) % 360;
+ }
+
+ private class MyOrientationEventListener
+ extends OrientationEventListener {
+ public MyOrientationEventListener(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onOrientationChanged(int orientation) {
+ if (mMediaRecorderRecording) return;
+ // We keep the last known orientation. So if the user first orient
+ // the camera then point the camera to floor or sky, we still have
+ // the correct orientation.
+ if (orientation == ORIENTATION_UNKNOWN) return;
+ mOrientation = roundOrientation(orientation);
+ // When the screen is unlocked, display rotation may change. Always
+ // calculate the up-to-date orientationCompensation.
+ int orientationCompensation = mOrientation
+ + Util.getDisplayRotation(VideoCamera.this);
+ if (mOrientationCompensation != orientationCompensation) {
+ mOrientationCompensation = orientationCompensation;
+ if (!mIsVideoCaptureIntent) {
+ setOrientationIndicator(mOrientationCompensation);
+ }
+ mHeadUpDisplay.setOrientation(mOrientationCompensation);
+ }
+ }
+ }
+
+ private void setOrientationIndicator(int degree) {
+ ((RotateImageView) findViewById(
+ R.id.review_thumbnail)).setDegree(degree);
+ ((RotateImageView) findViewById(
+ R.id.camera_switch_icon)).setDegree(degree);
+ ((RotateImageView) findViewById(
+ R.id.video_switch_icon)).setDegree(degree);
+ }
+
@Override
protected void onStart() {
super.onStart();
@@ -443,7 +489,8 @@ public class VideoCamera extends NoSearchActivity
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_retake:
- discardCurrentVideoAndInitRecorder();
+ deleteCurrentVideo();
+ hideAlert();
break;
case R.id.btn_play:
startPlayVideoActivity();
@@ -473,7 +520,6 @@ public class VideoCamera extends NoSearchActivity
}
} else {
stopVideoRecordingAndGetThumbnail();
- initializeRecorder();
}
}
@@ -484,11 +530,7 @@ public class VideoCamera extends NoSearchActivity
if (mMediaRecorderRecording) {
onStopVideoRecording(true);
- } else if (mMediaRecorder != null) {
- // If the click comes before recorder initialization, it is
- // ignored. If users click the button during initialization,
- // the event is put in the queue and record will be started
- // eventually.
+ } else {
startVideoRecording();
}
mShutterButton.setEnabled(false);
@@ -498,11 +540,6 @@ public class VideoCamera extends NoSearchActivity
}
}
- private void discardCurrentVideoAndInitRecorder() {
- deleteCurrentVideo();
- hideAlertAndInitializeRecorder();
- }
-
private OnScreenHint mStorageHint;
private void updateAndShowStorageHint(boolean mayHaveSd) {
@@ -589,6 +626,9 @@ public class VideoCamera extends NoSearchActivity
super.onResume();
mPausing = false;
+ // Start orientation listener as soon as possible because it takes
+ // some time to get first orientation.
+ mOrientationListener.enable();
mVideoPreview.setVisibility(View.VISIBLE);
readVideoPreferences();
resizeForPreviewAspectRatio();
@@ -615,11 +655,9 @@ public class VideoCamera extends NoSearchActivity
}
}, 200);
- if (mSurfaceHolder != null) {
- mHandler.sendEmptyMessage(INIT_RECORDER);
- }
-
changeHeadUpDisplayState();
+
+ updateThumbnailButton();
}
private void setPreviewDisplay(SurfaceHolder holder) {
@@ -639,7 +677,6 @@ public class VideoCamera extends NoSearchActivity
mCameraDevice = CameraHolder.instance().open(mCameraId);
}
- mCameraDevice.lock();
if (mPreviewing == true) {
mCameraDevice.stopPreview();
mPreviewing = false;
@@ -655,13 +692,6 @@ public class VideoCamera extends NoSearchActivity
closeCamera();
throw new RuntimeException("startPreview failed", ex);
}
-
- // If setPreviewDisplay has been set with a valid surface, unlock now.
- // If surface is null, unlock later. Otherwise, setPreviewDisplay in
- // surfaceChanged will fail.
- if (mSurfaceHolder != null) {
- mCameraDevice.unlock();
- }
}
private void closeCamera() {
@@ -717,8 +747,7 @@ public class VideoCamera extends NoSearchActivity
mStorageHint = null;
}
- mHandler.removeMessages(INIT_RECORDER);
-
+ mOrientationListener.disable();
}
@Override
@@ -806,16 +835,9 @@ public class VideoCamera extends NoSearchActivity
// already started.
if (holder.isCreating()) {
setPreviewDisplay(holder);
- mCameraDevice.unlock();
- mHandler.sendEmptyMessage(INIT_RECORDER);
} else {
stopVideoRecording();
- // If video quality changes, the surface will change. But we need to
- // initialize the recorder here. So collpase the head-up display to
- // keep the state of recorder consistent.
- mHeadUpDisplay.collapse();
restartPreview();
- initializeRecorder();
}
}
@@ -901,11 +923,8 @@ public class VideoCamera extends NoSearchActivity
// Prepares media recorder.
private void initializeRecorder() {
Log.v(TAG, "initializeRecorder");
- if (mMediaRecorder != null) return;
-
- // We will call initializeRecorder() again when the alert is hidden.
// If the mCameraDevice is null, then this activity is going to finish
- if (isAlertVisible() || mCameraDevice == null) return;
+ if (mCameraDevice == null) return;
Intent intent = getIntent();
Bundle myExtras = intent.getExtras();
@@ -927,6 +946,8 @@ public class VideoCamera extends NoSearchActivity
}
mMediaRecorder = new MediaRecorder();
+ // Unlock the camera object before passing it to media recorder.
+ mCameraDevice.unlock();
mMediaRecorder.setCamera(mCameraDevice);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
@@ -972,22 +993,29 @@ public class VideoCamera extends NoSearchActivity
// on the size restriction.
}
+ // See android.hardware.Camera.Parameters.setRotation for
+ // documentation.
+ int rotation = 0;
+ if (mOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
+ CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
+ if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
+ rotation = (info.orientation - mOrientation + 360) % 360;
+ } else { // back-facing camera
+ rotation = (info.orientation + mOrientation) % 360;
+ }
+ }
+ mMediaRecorder.setOrientationHint(rotation);
+
try {
mMediaRecorder.prepare();
} catch (IOException e) {
- Log.e(TAG, "prepare failed for " + mVideoFilename);
+ Log.e(TAG, "prepare failed for " + mVideoFilename, e);
releaseMediaRecorder();
throw new RuntimeException(e);
}
- mMediaRecorderRecording = false;
- // Update the last video thumbnail.
- if (!mIsVideoCaptureIntent) {
- if (!mThumbController.isUriValid()) {
- updateLastVideo();
- }
- mThumbController.updateDisplayIfNeeded();
- }
+ mMediaRecorder.setOnErrorListener(this);
+ mMediaRecorder.setOnInfoListener(this);
}
private void releaseMediaRecorder() {
@@ -998,6 +1026,8 @@ public class VideoCamera extends NoSearchActivity
mMediaRecorder.release();
mMediaRecorder = null;
}
+ // Take back the camera object control from media recorder.
+ mCameraDevice.lock();
}
private void createVideoPath() {
@@ -1109,7 +1139,6 @@ public class VideoCamera extends NoSearchActivity
stopVideoRecording();
}
closeCamera();
- mHandler.removeMessages(INIT_RECORDER);
// Reload the preferences.
mPreferences.setLocalId(this, mCameraId);
@@ -1121,10 +1150,6 @@ public class VideoCamera extends NoSearchActivity
// Reload the UI.
initializeHeadUpDisplay();
-
- if (mSurfaceHolder != null) {
- mHandler.sendEmptyMessage(INIT_RECORDER);
- }
}
private PreferenceGroup filterPreferenceScreenByIntent(
@@ -1180,39 +1205,35 @@ public class VideoCamera extends NoSearchActivity
private void startVideoRecording() {
Log.v(TAG, "startVideoRecording");
- if (!mMediaRecorderRecording) {
-
- if (mStorageStatus != STORAGE_STATUS_OK) {
- Log.v(TAG, "Storage issue, ignore the start request");
- return;
- }
-
- // Check mMediaRecorder to see whether it is initialized or not.
- if (mMediaRecorder == null) {
- Log.e(TAG, "MediaRecorder is not initialized.");
- return;
- }
+ if (mStorageStatus != STORAGE_STATUS_OK) {
+ Log.v(TAG, "Storage issue, ignore the start request");
+ return;
+ }
- pauseAudioPlayback();
+ initializeRecorder();
+ if (mMediaRecorder == null) {
+ Log.e(TAG, "Fail to initialize media recorder");
+ return;
+ }
- try {
- mMediaRecorder.setOnErrorListener(this);
- mMediaRecorder.setOnInfoListener(this);
- mMediaRecorder.start(); // Recording is now started
- } catch (RuntimeException e) {
- Log.e(TAG, "Could not start media recorder. ", e);
- return;
- }
- mHeadUpDisplay.setEnabled(false);
+ pauseAudioPlayback();
- mMediaRecorderRecording = true;
- mRecordingStartTime = SystemClock.uptimeMillis();
- updateRecordingIndicator(false);
- mRecordingTimeView.setText("");
- mRecordingTimeView.setVisibility(View.VISIBLE);
- updateRecordingTime();
- keepScreenOn();
+ try {
+ mMediaRecorder.start(); // Recording is now started
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Could not start media recorder. ", e);
+ releaseMediaRecorder();
+ return;
}
+ mHeadUpDisplay.setEnabled(false);
+
+ mMediaRecorderRecording = true;
+ mRecordingStartTime = SystemClock.uptimeMillis();
+ updateRecordingIndicator(false);
+ mRecordingTimeView.setText("");
+ mRecordingTimeView.setVisibility(View.VISIBLE);
+ updateRecordingTime();
+ keepScreenOn();
}
private void updateRecordingIndicator(boolean showRecording) {
@@ -1302,35 +1323,32 @@ public class VideoCamera extends NoSearchActivity
private void stopVideoRecording() {
Log.v(TAG, "stopVideoRecording");
- boolean needToRegisterRecording = false;
- if (mMediaRecorderRecording || mMediaRecorder != null) {
- if (mMediaRecorderRecording && mMediaRecorder != null) {
- try {
- mMediaRecorder.setOnErrorListener(null);
- mMediaRecorder.setOnInfoListener(null);
- mMediaRecorder.stop();
- mCurrentVideoFilename = mVideoFilename;
- Log.v(TAG, "Setting current video filename: "
- + mCurrentVideoFilename);
- needToRegisterRecording = true;
- } catch (RuntimeException e) {
- Log.e(TAG, "stop fail: " + e.getMessage());
- deleteVideoFile(mVideoFilename);
- }
- mHeadUpDisplay.setEnabled(true);
- mMediaRecorderRecording = false;
+ if (mMediaRecorderRecording) {
+ boolean needToRegisterRecording = false;
+ mMediaRecorder.setOnErrorListener(null);
+ mMediaRecorder.setOnInfoListener(null);
+ try {
+ mMediaRecorder.stop();
+ mCurrentVideoFilename = mVideoFilename;
+ Log.v(TAG, "Setting current video filename: "
+ + mCurrentVideoFilename);
+ needToRegisterRecording = true;
+ } catch (RuntimeException e) {
+ Log.e(TAG, "stop fail: " + e.getMessage());
+ deleteVideoFile(mVideoFilename);
}
- releaseMediaRecorder();
+ mMediaRecorderRecording = false;
+ mHeadUpDisplay.setEnabled(true);
updateRecordingIndicator(true);
mRecordingTimeView.setVisibility(View.GONE);
keepScreenOnAwhile();
+ if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) {
+ registerVideo();
+ }
+ mVideoFilename = null;
+ mVideoFileDescriptor = null;
}
- if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) {
- registerVideo();
- }
-
- mVideoFilename = null;
- mVideoFileDescriptor = null;
+ releaseMediaRecorder(); // always release media recorder
}
private void resetScreenOn() {
@@ -1349,21 +1367,27 @@ public class VideoCamera extends NoSearchActivity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
- private void hideAlertAndInitializeRecorder() {
- hideAlert();
- mHandler.sendEmptyMessage(INIT_RECORDER);
- }
-
private void acquireVideoThumb() {
Bitmap videoFrame = ThumbnailUtils.createVideoThumbnail(
mCurrentVideoFilename, Video.Thumbnails.MINI_KIND);
mThumbController.setData(mCurrentVideoUri, videoFrame);
+ mThumbController.updateDisplayIfNeeded();
}
private static ImageManager.DataLocation dataLocation() {
return ImageManager.DataLocation.EXTERNAL;
}
+ private void updateThumbnailButton() {
+ // Update the last video thumbnail.
+ if (!mIsVideoCaptureIntent) {
+ if (!mThumbController.isUriValid()) {
+ updateLastVideo();
+ }
+ mThumbController.updateDisplayIfNeeded();
+ }
+ }
+
private void updateLastVideo() {
IImageList list = ImageManager.makeImageList(
mContentResolver,
@@ -1532,18 +1556,7 @@ public class VideoCamera extends NoSearchActivity
resizeForPreviewAspectRatio();
restartPreview(); // Parameters will be set in startPreview().
} else {
- try {
- // We need to lock the camera before writing parameters.
- mCameraDevice.lock();
- } catch (RuntimeException e) {
- // When preferences are added for the first time, this method
- // will be called. But OnScreenSetting is not displayed yet and
- // media recorder still owns the camera. Lock will fail and we
- // just ignore it.
- return;
- }
setCameraParameters();
- mCameraDevice.unlock();
}
}
@@ -1569,19 +1582,6 @@ public class VideoCamera extends NoSearchActivity
}
public void onPopupWindowVisibilityChanged(final int visibility) {
- mHandler.post(new Runnable() {
- public void run() {
- VideoCamera.this.onPopupWindowVisibilityChanged(visibility);
- }
- });
- }
- }
-
- private void onPopupWindowVisibilityChanged(int visibility) {
- if (visibility == GLView.VISIBLE) {
- releaseMediaRecorder();
- } else {
- if (!mPausing && mSurfaceHolder != null) initializeRecorder();
}
}
diff --git a/src/com/android/camera/ui/CamcorderHeadUpDisplay.java b/src/com/android/camera/ui/CamcorderHeadUpDisplay.java
index 8e98100..0c2454f 100644
--- a/src/com/android/camera/ui/CamcorderHeadUpDisplay.java
+++ b/src/com/android/camera/ui/CamcorderHeadUpDisplay.java
@@ -27,11 +27,18 @@ public class CamcorderHeadUpDisplay extends HeadUpDisplay {
private static final String TAG = "CamcorderHeadUpDisplay";
private OtherSettingsIndicator mOtherSettings;
+ private int mInitialOrientation;
public CamcorderHeadUpDisplay(Context context) {
super(context);
}
+ public void initialize(Context context, PreferenceGroup group,
+ int initialOrientation) {
+ mInitialOrientation = initialOrientation;
+ super.initialize(context, group);
+ }
+
@Override
protected void initializeIndicatorBar(
Context context, PreferenceGroup group) {
@@ -59,5 +66,7 @@ public class CamcorderHeadUpDisplay extends HeadUpDisplay {
addIndicator(context, group, CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE);
addIndicator(context, group, CameraSettings.KEY_VIDEO_QUALITY);
addIndicator(context, group, CameraSettings.KEY_CAMERA_ID);
+
+ mIndicatorBar.setOrientation(mInitialOrientation);
}
}