summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/CaptureModule.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/camera/CaptureModule.java')
-rw-r--r--src/com/android/camera/CaptureModule.java266
1 files changed, 240 insertions, 26 deletions
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index c31658ae8..7c6e5e73b 100644
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -19,6 +19,7 @@
package com.android.camera;
+import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -42,6 +43,7 @@ import android.media.CameraProfile;
import android.media.Image;
import android.media.ImageReader;
import android.net.Uri;
+import android.os.Debug;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -58,8 +60,11 @@ import android.widget.Toast;
import com.android.camera.PhotoModule.NamedImages;
import com.android.camera.PhotoModule.NamedImages.NamedEntity;
+import com.android.camera.ui.CountDownView;
import com.android.camera.ui.RotateTextToast;
import com.android.camera.util.CameraUtil;
+import com.android.camera.util.PersistUtil;
+import com.android.internal.util.MemInfoReader;
import org.codeaurora.snapcam.R;
import org.codeaurora.snapcam.filter.ClearSightImageProcessor;
@@ -76,7 +81,7 @@ import java.util.concurrent.TimeUnit;
public class CaptureModule implements CameraModule, PhotoController,
MediaSaveService.Listener, ClearSightImageProcessor.Callback,
- SettingsManager.Listener {
+ SettingsManager.Listener, CountDownView.OnCountDownFinishedListener {
public static final int DUAL_MODE = 0;
public static final int BAYER_MODE = 1;
public static final int MONO_MODE = 2;
@@ -122,6 +127,11 @@ public class CaptureModule implements CameraModule, PhotoController,
private static final int STATE_WAITING_TOUCH_FOCUS = 5;
private static final String TAG = "SnapCam_CaptureModule";
+ // Used for check memory status for longshot mode
+ // Currently, this cancel threshold selection is based on test experiments,
+ // we can change it based on memory status or other requirements.
+ private static final int LONGSHOT_CANCEL_THRESHOLD = 40 * 1024 * 1024;
+
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
@@ -164,6 +174,11 @@ public class CaptureModule implements CameraModule, PhotoController,
private FocusStateListener mFocusStateListener;
private LocationManager mLocationManager;
private SettingsManager mSettingsManager;
+ private int mLongShotCaptureCount;
+ private int mLongShotCaptureCountLimit;
+ private long SECONDARY_SERVER_MEM;
+ private boolean mLongshotActive = false;
+
/**
* A {@link CameraCaptureSession } for camera preview.
*/
@@ -188,12 +203,51 @@ public class CaptureModule implements CameraModule, PhotoController,
private ImageReader[] mImageReader = new ImageReader[MAX_NUM_CAM];
private NamedImages mNamedImages;
private ContentResolver mContentResolver;
+
+ private class MediaSaveNotifyThread extends Thread {
+ private Uri uri;
+
+ public MediaSaveNotifyThread(Uri uri) {
+ this.uri = uri;
+ }
+
+ public void setUri(Uri uri) {
+ this.uri = uri;
+ }
+
+ public void run() {
+ while (mLongshotActive) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ }
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ if (uri != null)
+ mActivity.notifyNewMedia(uri);
+ mActivity.updateStorageSpaceAndHint();
+ }
+ });
+ mediaSaveNotifyThread = null;
+ }
+ }
+
+ private MediaSaveNotifyThread mediaSaveNotifyThread;
private MediaSaveService.OnMediaSavedListener mOnMediaSavedListener =
new MediaSaveService.OnMediaSavedListener() {
@Override
public void onMediaSaved(Uri uri) {
- if (uri != null) {
- mActivity.notifyNewMedia(uri);
+ if (mLongshotActive) {
+ if (mediaSaveNotifyThread == null) {
+ mediaSaveNotifyThread = new MediaSaveNotifyThread(uri);
+ mediaSaveNotifyThread.start();
+ } else
+ mediaSaveNotifyThread.setUri(uri);
+ } else {
+ if (uri != null) {
+ mActivity.notifyNewMedia(uri);
+ }
}
}
};
@@ -720,29 +774,79 @@ public class CaptureModule implements CameraModule, PhotoController,
captureBuilder.addTarget(mImageReader[id].getSurface());
mCaptureSession[id].stopRepeating();
- mCaptureSession[id].capture(captureBuilder.build(), new CameraCaptureSession.CaptureCallback() {
+ if (mLongshotActive) {
+ mCaptureSession[id].setRepeatingRequest(captureBuilder.build(), new
+ CameraCaptureSession.CaptureCallback() {
- @Override
- public void onCaptureCompleted(CameraCaptureSession session,
- CaptureRequest request,
- TotalCaptureResult result) {
- Log.d(TAG, "captureStillPicture onCaptureCompleted: " + id);
- }
+ @Override
+ public void onCaptureCompleted(CameraCaptureSession session,
+ CaptureRequest request,
+ TotalCaptureResult result) {
+ Log.d(TAG, "captureStillPicture Longshot onCaptureCompleted: " + id);
+ mActivity.updateStorageSpaceAndHint();
+ if (checkLongShotMemoAndLimit()) {
+ cancelAutoFocus();
+ return;
+ }
+ mActivity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mUI.doShutterAnimation();
+ }
+ });
+ mLongShotCaptureCount++;
+ }
- @Override
- public void onCaptureFailed(CameraCaptureSession session,
- CaptureRequest request,
- CaptureFailure result) {
- Log.d(TAG, "captureStillPicture onCaptureFailed: " + id);
- }
+ @Override
+ public void onCaptureFailed(CameraCaptureSession session,
+ CaptureRequest request,
+ CaptureFailure result) {
+ Log.d(TAG, "captureStillPicture Longshot onCaptureFailed: " + id);
+ if (checkLongShotMemoAndLimit()) {
+ cancelAutoFocus();
+ return;
+ }
+ mActivity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mUI.doShutterAnimation();
+ }
+ });
+ }
- @Override
- public void onCaptureSequenceCompleted(CameraCaptureSession session, int
- sequenceId, long frameNumber) {
- Log.d(TAG, "captureStillPicture onCaptureSequenceCompleted: " + id);
- unlockFocus(id);
- }
- }, mCaptureCallbackHandler);
+ @Override
+ public void onCaptureSequenceCompleted(CameraCaptureSession session, int
+ sequenceId, long frameNumber) {
+ Log.d(TAG, "captureStillPicture Longshot onCaptureSequenceCompleted: " +
+ id);
+ unlockFocus(id);
+ }
+ }, mCaptureCallbackHandler);
+ } else {
+ mCaptureSession[id].capture(captureBuilder.build(), new CameraCaptureSession.CaptureCallback() {
+
+ @Override
+ public void onCaptureCompleted(CameraCaptureSession session,
+ CaptureRequest request,
+ TotalCaptureResult result) {
+ Log.d(TAG, "captureStillPicture onCaptureCompleted: " + id);
+ }
+
+ @Override
+ public void onCaptureFailed(CameraCaptureSession session,
+ CaptureRequest request,
+ CaptureFailure result) {
+ Log.d(TAG, "captureStillPicture onCaptureFailed: " + id);
+ }
+
+ @Override
+ public void onCaptureSequenceCompleted(CameraCaptureSession session, int
+ sequenceId, long frameNumber) {
+ Log.d(TAG, "captureStillPicture onCaptureSequenceCompleted: " + id);
+ unlockFocus(id);
+ }
+ }, mCaptureCallbackHandler);
+ }
}
} catch (CameraAccessException e) {
Log.d(TAG, "Capture still picture has failed");
@@ -1095,6 +1199,7 @@ public class CaptureModule implements CameraModule, PhotoController,
initializeSecondTime();
}
mUI.hidePreviewCover();
+ mActivity.updateStorageSpaceAndHint();
mUI.enableShutter(true);
}
@@ -1251,7 +1356,8 @@ public class CaptureModule implements CameraModule, PhotoController,
@Override
public void onCountDownFinished() {
-
+ mUI.showUIAfterCountDown();
+ takePicture();
}
@Override
@@ -1372,17 +1478,125 @@ public class CaptureModule implements CameraModule, PhotoController,
@Override
public void onShutterButtonFocus(boolean pressed) {
-
+ if (!pressed && mLongshotActive) {
+ cancelLongshot();
+ }
}
@Override
public void onShutterButtonClick() {
- takePicture();
+ String timer = mSettingsManager.getValue(SettingsManager.KEY_TIMER);
+
+ int seconds = Integer.parseInt(timer);
+ // When shutter button is pressed, check whether the previous countdown is
+ // finished. If not, cancel the previous countdown and start a new one.
+ if (mUI.isCountingDown()) {
+ mUI.cancelCountDown();
+ }
+ if (seconds > 0) {
+ mUI.startCountDown(seconds, true);
+ } else {
+ takePicture();
+ }
}
@Override
public void onShutterButtonLongClick() {
+ if (isBackMode() && getMode() == DUAL_MODE) return;
+ if (mActivity.getStorageSpaceBytes() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
+ Log.i(TAG, "Not enough space or storage not ready. remaining="
+ + mActivity.getStorageSpaceBytes());
+ return;
+ }
+
+ String longshot = mSettingsManager.getValue(SettingsManager.KEY_LONGSHOT);
+ if (longshot.equals("on")) {
+ //Cancel the previous countdown when long press shutter button for longshot.
+ if (mUI.isCountingDown()) {
+ mUI.cancelCountDown();
+ }
+ //check whether current memory is enough for longshot.
+ mActivity.updateStorageSpaceAndHint();
+
+ if (isLongshotNeedCancel()) {
+ mLongshotActive = false;
+ return;
+ }
+ mLongShotCaptureCountLimit = PersistUtil.getLongshotShotLimit();
+ mLongShotCaptureCount = 1;
+ mLongshotActive = true;
+ takePicture();
+ }
+ }
+
+ private void cancelLongshot() {
+ Log.d(TAG, "cancelLongshot");
+ mLongshotActive = false;
+ try {
+ if (isBackMode()) {
+ switch (getMode()) {
+ case BAYER_MODE:
+ mCaptureSession[BAYER_ID].stopRepeating();
+ break;
+ case MONO_MODE:
+ mCaptureSession[MONO_MODE].stopRepeating();
+ break;
+ }
+ } else {
+ mCaptureSession[FRONT_ID].stopRepeating();
+ }
+ } catch (CameraAccessException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private boolean isLongshotNeedCancel() {
+ if (PersistUtil.getSkipMemoryCheck()) {
+ return false;
+ }
+ if (Storage.getAvailableSpace() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
+ Log.w(TAG, "current storage is full");
+ return true;
+ }
+ if (SECONDARY_SERVER_MEM == 0) {
+ ActivityManager am = (ActivityManager) mActivity.getSystemService(
+ Context.ACTIVITY_SERVICE);
+ ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
+ am.getMemoryInfo(memInfo);
+ SECONDARY_SERVER_MEM = memInfo.secondaryServerThreshold;
+ }
+
+ long totalMemory = Runtime.getRuntime().totalMemory();
+ long maxMemory = Runtime.getRuntime().maxMemory();
+ long remainMemory = maxMemory - totalMemory;
+
+ MemInfoReader reader = new MemInfoReader();
+ reader.readMemInfo();
+ long[] info = reader.getRawInfo();
+ long availMem = (info[Debug.MEMINFO_FREE] + info[Debug.MEMINFO_CACHED]) * 1024;
+
+ if (availMem <= SECONDARY_SERVER_MEM || remainMemory <= LONGSHOT_CANCEL_THRESHOLD) {
+ Log.e(TAG, "cancel longshot: free=" + info[Debug.MEMINFO_FREE] * 1024
+ + " cached=" + info[Debug.MEMINFO_CACHED] * 1024
+ + " threshold=" + SECONDARY_SERVER_MEM);
+ RotateTextToast.makeText(mActivity, R.string.msg_cancel_longshot_for_limited_memory,
+ Toast.LENGTH_SHORT).show();
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean checkLongShotMemoAndLimit() {
+ if (isLongshotNeedCancel()) {
+ return true;
+ }
+
+ if (mLongShotCaptureCount == mLongShotCaptureCountLimit) {
+ return true;
+ }
+ return false;
}
private boolean isFlashOff(int id) {