summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/WideAnglePanoramaModule.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/camera/WideAnglePanoramaModule.java')
-rw-r--r--src/com/android/camera/WideAnglePanoramaModule.java148
1 files changed, 113 insertions, 35 deletions
diff --git a/src/com/android/camera/WideAnglePanoramaModule.java b/src/com/android/camera/WideAnglePanoramaModule.java
index 0aab8f804..364e815ff 100644
--- a/src/com/android/camera/WideAnglePanoramaModule.java
+++ b/src/com/android/camera/WideAnglePanoramaModule.java
@@ -16,7 +16,6 @@
package com.android.camera;
-import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -68,9 +67,10 @@ public class WideAnglePanoramaModule
implements CameraModule, WideAnglePanoramaController,
SurfaceTexture.OnFrameAvailableListener {
- public static final int DEFAULT_SWEEP_ANGLE = 160;
+ public static final int DEFAULT_SWEEP_ANGLE_PORTRAIT = 160;
+ public static final int DEFAULT_SWEEP_ANGLE_LANDSCAPE = 270;
public static final int DEFAULT_BLEND_MODE = Mosaic.BLENDTYPE_HORIZONTAL;
- public static final int DEFAULT_CAPTURE_PIXELS = 960 * 720;
+ public static final int DEFAULT_CAPTURE_PIXELS = 1440 * 1000;
private static final int MSG_LOW_RES_FINAL_MOSAIC_READY = 1;
private static final int MSG_GENERATE_FINAL_MOSAIC_ERROR = 2;
@@ -124,15 +124,12 @@ public class WideAnglePanoramaModule
private float mHorizontalViewAngle;
private float mVerticalViewAngle;
- // Prefer FOCUS_MODE_INFINITY to FOCUS_MODE_CONTINUOUS_VIDEO because of
- // getting a better image quality by the former.
- private String mTargetFocusMode = Parameters.FOCUS_MODE_INFINITY;
-
private PanoOrientationEventListener mOrientationEventListener;
// The value could be 0, 90, 180, 270 for the 4 different orientations measured in clockwise
// respectively.
private int mDeviceOrientation;
private int mDeviceOrientationAtCapture;
+ private int mOrientationOffset;
private int mCameraOrientation;
private int mOrientationCompensation;
private boolean mOrientationLocked;
@@ -197,6 +194,7 @@ public class WideAnglePanoramaModule
// the camera then point the camera to floor or sky, we still have
// the correct orientation.
if (orientation == ORIENTATION_UNKNOWN) return;
+ orientation = (orientation - mOrientationOffset + 360) % 360;
int oldOrientation = mDeviceOrientation;
mDeviceOrientation = CameraUtil.roundOrientation(orientation, mDeviceOrientation);
// When the screen is unlocked, display rotation may change. Always
@@ -230,6 +228,7 @@ public class WideAnglePanoramaModule
public void init(CameraActivity activity, View parent) {
mActivity = activity;
mRootView = parent;
+ mOrientationOffset = CameraUtil.isDefaultToPortrait(mActivity) ? 0 : 90;
mOrientationManager = new OrientationManager(activity);
mCaptureState = CAPTURE_STATE_VIEWFINDER;
@@ -310,6 +309,9 @@ public class WideAnglePanoramaModule
CameraSettings.upgradeGlobalPreferences(mPreferences.getGlobal(), activity);
mLocationManager = new LocationManager(mActivity, null);
+ // Power shutter
+ mActivity.initPowerShutter(mPreferences);
+
mMainHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -427,7 +429,7 @@ public class WideAnglePanoramaModule
int w = size.width;
// we only want 4:3 format.
int d = DEFAULT_CAPTURE_PIXELS - h * w;
- if (needSmaller && d < 0) { // no bigger preview than 960x720.
+ if (needSmaller && d < 0) {
continue;
}
if (need4To3 && (h * 4 != w * 3)) {
@@ -456,6 +458,7 @@ public class WideAnglePanoramaModule
Log.d(TAG, "camera preview h = "
+ mCameraPreviewHeight + " , w = " + mCameraPreviewWidth);
parameters.setPreviewSize(mCameraPreviewWidth, mCameraPreviewHeight);
+ mUI.setPreviewSize(mCameraPreviewWidth, mCameraPreviewHeight);
List<int[]> frameRates = parameters.getSupportedPreviewFpsRange();
int last = frameRates.size() - 1;
@@ -464,12 +467,13 @@ public class WideAnglePanoramaModule
parameters.setPreviewFpsRange(minFps, maxFps);
Log.d(TAG, "preview fps: " + minFps + ", " + maxFps);
+ // use CAF for viewfinder until starting the real mosaic, then lock
List<String> supportedFocusModes = parameters.getSupportedFocusModes();
- if (supportedFocusModes.indexOf(mTargetFocusMode) >= 0) {
- parameters.setFocusMode(mTargetFocusMode);
+ if (supportedFocusModes.indexOf(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) >= 0) {
+ parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
} else {
// Use the default focus mode and log a message
- Log.w(TAG, "Cannot set the focus mode to " + mTargetFocusMode +
+ Log.w(TAG, "Cannot set the focus mode to " + Parameters.FOCUS_MODE_CONTINUOUS_PICTURE +
" becuase the mode is not supported.");
}
@@ -567,15 +571,28 @@ public class WideAnglePanoramaModule
public void startCapture() {
// Reset values so we can do this again.
+
+ Parameters parameters = mCameraDevice.getParameters();
+ List<String> supportedFocusModes = parameters.getSupportedFocusModes();
+ if (supportedFocusModes.indexOf(Parameters.FOCUS_MODE_FIXED) >= 0) {
+ parameters.setFocusMode(Parameters.FOCUS_MODE_FIXED);
+ } else {
+ // Use the default focus mode and log a message
+ Log.w(TAG, "Cannot set the focus mode to " + Parameters.FOCUS_MODE_FIXED +
+ " becuase the mode is not supported.");
+ }
+ parameters.setAutoExposureLock(true);
+ parameters.setAutoWhiteBalanceLock(true);
+ configureCamera(parameters);
+
mCancelComputation = false;
mTimeTaken = System.currentTimeMillis();
mActivity.setSwipingEnabled(false);
mCaptureState = CAPTURE_STATE_MOSAIC;
mUI.onStartCapture();
- Parameters parameters = mCameraDevice.getParameters();
- parameters.setAutoExposureLock(true);
- parameters.setAutoWhiteBalanceLock(true);
- configureCamera(parameters);
+
+ final int sweepAngle = (mDeviceOrientation == 90 || mDeviceOrientation == 270) ?
+ DEFAULT_SWEEP_ANGLE_LANDSCAPE : DEFAULT_SWEEP_ANGLE_PORTRAIT;
mMosaicFrameProcessor.setProgressListener(new MosaicFrameProcessor.ProgressListener() {
@Override
@@ -585,8 +602,8 @@ public class WideAnglePanoramaModule
float accumulatedVerticalAngle = progressY * mVerticalViewAngle;
boolean isRotated = !(mDeviceOrientationAtCapture == mDeviceOrientation);
if (isFinished
- || (Math.abs(accumulatedHorizontalAngle) >= DEFAULT_SWEEP_ANGLE)
- || (Math.abs(accumulatedVerticalAngle) >= DEFAULT_SWEEP_ANGLE)
+ || (Math.abs(accumulatedHorizontalAngle) >= sweepAngle)
+ || (Math.abs(accumulatedVerticalAngle) >= sweepAngle)
|| isRotated) {
stopCapture(false);
} else {
@@ -606,7 +623,7 @@ public class WideAnglePanoramaModule
mUI.resetCaptureProgress();
// TODO: calculate the indicator width according to different devices to reflect the actual
// angle of view of the camera device.
- mUI.setMaxCaptureProgress(DEFAULT_SWEEP_ANGLE);
+ mUI.setMaxCaptureProgress(sweepAngle);
mUI.showCaptureProgress();
mDeviceOrientationAtCapture = mDeviceOrientation;
keepScreenOn();
@@ -624,6 +641,14 @@ public class WideAnglePanoramaModule
Parameters parameters = mCameraDevice.getParameters();
parameters.setAutoExposureLock(false);
parameters.setAutoWhiteBalanceLock(false);
+ List<String> supportedFocusModes = parameters.getSupportedFocusModes();
+ if (supportedFocusModes.indexOf(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) >= 0) {
+ parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ } else {
+ // Use the default focus mode and log a message
+ Log.w(TAG, "Cannot set the focus mode to " + Parameters.FOCUS_MODE_CONTINUOUS_PICTURE +
+ " becuase the mode is not supported.");
+ }
configureCamera(parameters);
mMosaicFrameProcessor.setProgressListener(null);
@@ -701,13 +726,21 @@ public class WideAnglePanoramaModule
} catch (InterruptedException e) {
throw new RuntimeException("Panorama reportProgress failed", e);
}
- // Update the progress bar
- mActivity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mUI.updateSavingProgress(progress);
- }
- });
+ // Update the progress bar if we haven't paused. In the case where
+ // we pause the UI, then launch the camera from the lockscreen with
+ // this thread still running, a new WideAnglePanoramaModule is
+ // created, but this thread is left running to finish the task (and
+ // mPaused continues to be true for that instance.
+ if (!mPaused) {
+ mActivity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (!mPaused) {
+ mUI.updateSavingProgress(progress);
+ }
+ }
+ });
+ }
}
}
};
@@ -725,9 +758,11 @@ public class WideAnglePanoramaModule
if (mUsingFrontCamera) {
// mCameraOrientation is negative with respect to the front facing camera.
// See document of android.hardware.Camera.Parameters.setRotation.
- orientation = (mDeviceOrientationAtCapture - mCameraOrientation - 360) % 360;
+ orientation = (mDeviceOrientationAtCapture - mCameraOrientation -
+ mOrientationOffset + 360) % 360;
} else {
- orientation = (mDeviceOrientationAtCapture + mCameraOrientation) % 360;
+ orientation = (mDeviceOrientationAtCapture + mCameraOrientation +
+ mOrientationOffset) % 360;
}
return orientation;
}
@@ -882,12 +917,7 @@ public class WideAnglePanoramaModule
return;
}
- int perct = 100;
- final ActivityManager am = (ActivityManager)
- mActivity.getSystemService(Context.ACTIVITY_SERVICE);
- if (am.isLowRamDevice()) {
- perct = mActivity.getResources().getInteger(R.integer.panorama_frame_size_reduction);
- }
+ int perct = mActivity.getResources().getInteger(R.integer.panorama_frame_size_reduction);
int width = (mCameraPreviewWidth * perct) / 100;
int height = (mCameraPreviewHeight * perct) / 100;
@@ -943,6 +973,10 @@ public class WideAnglePanoramaModule
}
mUI.showPreviewCover();
releaseCamera();
+
+ // Load the power shutter
+ mActivity.initPowerShutter(mPreferences);
+
synchronized (mRendererLock) {
mCameraTexture = null;
@@ -1139,6 +1173,13 @@ public class WideAnglePanoramaModule
mCameraTexture.setOnFrameAvailableListener(this);
mCameraDevice.setPreviewTexture(mCameraTexture);
}
+ mCameraDevice.setOneShotPreviewCallback(mMainHandler,
+ new CameraManager.CameraPreviewDataCallback() {
+ @Override
+ public void onPreviewFrame(byte[] data, CameraProxy camera) {
+ mUI.hidePreviewCover();
+ }
+ });
mCameraDevice.startPreview();
mCameraState = PREVIEW_ACTIVE;
}
@@ -1216,7 +1257,7 @@ public class WideAnglePanoramaModule
@Override
public void cancelHighResStitching() {
- if (mPaused || mCameraTexture == null) return;
+ if (mPaused) return;
cancelHighResComputation();
}
@@ -1235,14 +1276,51 @@ public class WideAnglePanoramaModule
public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
-
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
+ // Do not handle any key if the activity is paused
+ // or not in active camera/video mode
+ if (mPaused) {
+ return true;
+ } else if (!mActivity.isInCameraApp()) {
+ return false;
+ }
+
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_MEDIA_NEXT:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ return true;
+ case KeyEvent.KEYCODE_CAMERA:
+ case KeyEvent.KEYCODE_HEADSETHOOK:
+ if (event.getRepeatCount() == 0) {
+ onShutterButtonClick();
+ }
+ return true;
+ case KeyEvent.KEYCODE_POWER:
+ return true;
+ }
return false;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_MEDIA_NEXT:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ if (!CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()) {
+ onShutterButtonClick();
+ }
+ return true;
+ case KeyEvent.KEYCODE_POWER:
+ if (CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()) {
+ onShutterButtonClick();
+ }
+ return true;
+ }
return false;
}