summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/PhotoModule.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/camera/PhotoModule.java')
-rw-r--r--src/com/android/camera/PhotoModule.java97
1 files changed, 72 insertions, 25 deletions
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 176885ce4..4444e4d38 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -25,6 +25,7 @@ import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
@@ -140,9 +141,9 @@ public class PhotoModule
private static final int UPDATE_PARAM_PREFERENCE = 4;
private static final int UPDATE_PARAM_ALL = -1;
- // This is the timeout to keep the camera in onPause for the first time
- // after screen on if the activity is started from secure lock screen.
- private static final int KEEP_CAMERA_TIMEOUT = 1000; // ms
+ // This is the delay before we execute onResume tasks when coming
+ // from the lock screen, to allow time for onPause to execute.
+ private static final int ON_RESUME_TASKS_DELAY_MSEC = 20;
private static final String DEBUG_IMAGE_PREFIX = "DEBUG_";
@@ -297,6 +298,7 @@ public class PhotoModule
private String mCurrTouchAfAec = Parameters.TOUCH_AF_AEC_ON;
private final Handler mHandler = new MainHandler();
+
private PreferenceGroup mPreferenceGroup;
private boolean mQuickCapture;
@@ -343,6 +345,10 @@ public class PhotoModule
* application
*/
private class MainHandler extends Handler {
+ public MainHandler() {
+ super(Looper.getMainLooper());
+ }
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -576,6 +582,7 @@ public class PhotoModule
mCameraDevice = CameraUtil.openCamera(
mActivity, mCameraId, mHandler,
mActivity.getCameraOpenErrorCallback());
+
if (mCameraDevice == null) {
Log.e(TAG, "Failed to open camera:" + mCameraId + ", aborting.");
return;
@@ -624,6 +631,11 @@ public class PhotoModule
if (mFocusManager != null) mFocusManager.setPreviewSize(width, height);
}
+ @Override
+ public void onPreviewRectChanged(Rect previewRect) {
+ if (mFocusManager != null) mFocusManager.setPreviewRect(previewRect);
+ }
+
private void resetExposureCompensation() {
String value = mPreferences.getString(CameraSettings.KEY_EXPOSURE,
CameraSettings.EXPOSURE_DEFAULT_VALUE);
@@ -1216,6 +1228,7 @@ public class PhotoModule
// is full then ignore.
if (mCameraDevice == null || mCameraState == SNAPSHOT_IN_PROGRESS
|| mCameraState == SWITCHING_CAMERA
+ || mActivity.getMediaSaveService() == null
|| mActivity.getMediaSaveService().isQueueFull()) {
return false;
}
@@ -1295,7 +1308,9 @@ public class PhotoModule
mFaceDetectionStarted = false;
}
UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
- UsageStatistics.ACTION_CAPTURE_DONE, "Photo");
+ UsageStatistics.ACTION_CAPTURE_DONE, "Photo", 0,
+ UsageStatistics.hashFileName(mNamedImages.mQueue.lastElement().title + ".jpg"),
+ mParameters.flatten());
return true;
}
@@ -1616,14 +1631,10 @@ public class PhotoModule
mPaused = false;
}
- /**
- * Opens the camera device.
- *
- * @return Whether the camera was opened successfully.
- */
private boolean prepareCamera() {
// We need to check whether the activity is paused before long
// operations to ensure that onPause() can be done ASAP.
+ Log.v(TAG, "Open camera device.");
mCameraDevice = CameraUtil.openCamera(
mActivity, mCameraId, mHandler,
mActivity.getCameraOpenErrorCallback());
@@ -1644,9 +1655,30 @@ public class PhotoModule
return true;
}
-
@Override
public void onResumeAfterSuper() {
+ // Add delay on resume from lock screen only, in order to to speed up
+ // the onResume --> onPause --> onResume cycle from lock screen.
+ // Don't do always because letting go of thread can cause delay.
+ String action = mActivity.getIntent().getAction();
+ if (MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA.equals(action)
+ || MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)) {
+ Log.v(TAG, "On resume, from lock screen.");
+ // Note: onPauseAfterSuper() will delete this runnable, so we will
+ // at most have 1 copy queued up.
+ mHandler.postDelayed(new Runnable() {
+ public void run() {
+ onResumeTasks();
+ }
+ }, ON_RESUME_TASKS_DELAY_MSEC);
+ } else {
+ Log.v(TAG, "On resume.");
+ onResumeTasks();
+ }
+ }
+
+ private void onResumeTasks() {
+ Log.v(TAG, "Executing onResumeTasks.");
if (mOpenCameraFail || mCameraDisabled) return;
mJpegPictureCallbackTime = 0;
@@ -1702,20 +1734,17 @@ public class PhotoModule
@Override
public void onPauseAfterSuper() {
- // When camera is started from secure lock screen for the first time
- // after screen on, the activity gets onCreate->onResume->onPause->onResume.
- // To reduce the latency, keep the camera for a short time so it does
- // not need to be opened again.
- if (mCameraDevice != null && mActivity.isSecureCamera()
- && CameraActivity.isFirstStartAfterScreenOn()) {
- CameraActivity.resetFirstStartAfterScreenOn();
- CameraHolder.instance().keep(KEEP_CAMERA_TIMEOUT);
- }
+ Log.v(TAG, "On pause.");
+ mUI.showPreviewCover();
+
// Reset the focus first. Camera CTS does not guarantee that
// cancelAutoFocus is allowed after preview stops.
if (mCameraDevice != null && mCameraState != PREVIEW_STOPPED) {
mCameraDevice.cancelAutoFocus();
}
+ // If the camera has not been opened asynchronously yet,
+ // and startPreview hasn't been called, then this is a no-op.
+ // (e.g. onResume -> onPause -> onResume).
stopPreview();
mNamedImages = null;
@@ -1931,11 +1960,19 @@ public class PhotoModule
}
private void closeCamera() {
+ Log.v(TAG, "Close camera device.");
if (mCameraDevice != null) {
mCameraDevice.setZoomChangeListener(null);
mCameraDevice.setFaceDetectionCallback(null, null);
mCameraDevice.setErrorCallback(null);
- CameraHolder.instance().release();
+
+ if (mActivity.isSecureCamera() && !CameraActivity.isFirstStartAfterScreenOn()) {
+ // Blocks until camera is actually released.
+ CameraHolder.instance().strongRelease();
+ } else {
+ CameraHolder.instance().release();
+ }
+
mFaceDetectionStarted = false;
mCameraDevice = null;
setCameraState(PREVIEW_STOPPED);
@@ -1963,26 +2000,31 @@ public class PhotoModule
startPreview();
}
- // This can only be called by UI Thread.
+ /** This can run on a background thread, post any view updates to MainHandler. */
private void startPreview() {
- if (mPaused) {
+ if (mPaused || mCameraDevice == null) {
return;
}
+
+ // Any decisions we make based on the surface texture state
+ // need to be protected.
SurfaceTexture st = mUI.getSurfaceTexture();
if (st == null) {
Log.w(TAG, "startPreview: surfaceTexture is not ready.");
return;
}
+
if (!mCameraPreviewParamsReady) {
Log.w(TAG, "startPreview: parameters for preview is not ready.");
return;
}
mCameraDevice.setErrorCallback(mErrorCallback);
-
- // ICS camera frameworks has a bug. Face detection state is not cleared
+ // ICS camera frameworks has a bug. Face detection state is not cleared 1589
// after taking a picture. Stop the preview to work around it. The bug
// was fixed in JB.
- if (mCameraState != PREVIEW_STOPPED) stopPreview();
+ if (mCameraState != PREVIEW_STOPPED) {
+ stopPreview();
+ }
setDisplayOrientation();
@@ -2436,6 +2478,11 @@ public class PhotoModule
Log.v(TAG, "Preview Size changed. Restart Preview");
mRestartPreview = true;
}
+
+ if(optimalSize.width != 0 && optimalSize.height != 0) {
+ mUI.updatePreviewAspectRatio((float) optimalSize.width
+ / (float) optimalSize.height);
+ }
Log.v(TAG, "Preview size is " + optimalSize.width + "x" + optimalSize.height);
// Since changing scene mode may change supported values, set scene mode