merge in ics-mr0-release history after reset to ics-mr0
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index d9340f5..d832adb 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -122,8 +122,8 @@
<string name="effect_background" msgid="6909716214852487679">"Arrière-plan"</string>
<string name="accessibility_shutter_button" msgid="2664037763232556307">"Bouton de l\'obturateur"</string>
<string name="accessibility_review_thumbnail" msgid="8961275263537513017">"Photo la plus récente"</string>
- <string name="accessibility_camera_picker" msgid="8807945470215734566">"Interrupteur des appareils photo avant et arrière"</string>
- <string name="accessibility_mode_picker" msgid="3264968460835265505">"Sélecteur du mode Appareil photo, Vidéo ou Panorama"</string>
+ <string name="accessibility_camera_picker" msgid="8807945470215734566">"Interrupteur des caméras avant et arrière"</string>
+ <string name="accessibility_mode_picker" msgid="3264968460835265505">"Sélecteur du mode Appareil photo, Vidéo ou Panoramique"</string>
<string name="accessibility_second_level_indicators" msgid="3855951632917627620">"Plus de paramètres"</string>
<string name="accessibility_back_to_first_level" msgid="5234411571109877131">"Fermer les paramètres"</string>
<string name="accessibility_zoom_control" msgid="1339909363226825709">"Contrôle du zoom"</string>
diff --git a/src/com/android/camera/ActivityBase.java b/src/com/android/camera/ActivityBase.java
index ec878ee..b2ef481 100644
--- a/src/com/android/camera/ActivityBase.java
+++ b/src/com/android/camera/ActivityBase.java
@@ -19,17 +19,25 @@
import com.android.camera.ui.PopupManager;
import android.app.Activity;
+import android.app.KeyguardManager;
import android.view.KeyEvent;
+import android.content.Context;
import android.content.Intent;
+import android.hardware.Camera;
import android.media.AudioManager;
import android.os.Bundle;
+import android.util.Log;
/**
* Superclass of Camera and VideoCamera activities.
*/
-public class ActivityBase extends Activity {
+abstract public class ActivityBase extends Activity {
+ private static final String TAG = "ActivityBase";
+ private static boolean LOGV = false;
private int mResultCodeForTesting;
+ private boolean mOnResumePending;
private Intent mResultDataForTesting;
+ protected Camera mCameraDevice;
@Override
public void onCreate(Bundle icicle) {
@@ -38,6 +46,42 @@
}
@Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ if (LOGV) Log.v(TAG, "onWindowFocusChanged.hasFocus=" + hasFocus
+ + ".mOnResumePending=" + mOnResumePending);
+ if (hasFocus && mOnResumePending) {
+ doOnResume();
+ mOnResumePending = false;
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // Don't grab the camera if in use by lockscreen. For example, face
+ // unlock may be using the camera. Camera may be already opened in
+ // onCreate. doOnResume should continue if mCameraDevice != null.
+ if (mCameraDevice == null && !hasWindowFocus() && isKeyguardLocked()) {
+ if (LOGV) Log.v(TAG, "onRsume. mOnResumePending=true");
+ mOnResumePending = true;
+ } else {
+ if (LOGV) Log.v(TAG, "onRsume. mOnResumePending=false");
+ doOnResume();
+ mOnResumePending = false;
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ if (LOGV) Log.v(TAG, "onPause");
+ super.onPause();
+ mOnResumePending = false;
+ }
+
+ // Put the code of onResume in this method.
+ abstract protected void doOnResume();
+
+ @Override
public boolean onSearchRequested() {
return false;
}
@@ -77,4 +121,10 @@
PopupManager.removeInstance(this);
super.onDestroy();
}
+
+ private boolean isKeyguardLocked() {
+ KeyguardManager kgm = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+ // isKeyguardSecure excludes the slide lock case.
+ return (kgm != null) && kgm.isKeyguardLocked() && kgm.isKeyguardSecure();
+ }
}
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 70f70c8..931095e 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -135,7 +135,6 @@
private static final String sTempCropFilename = "crop-temp";
- private android.hardware.Camera mCameraDevice;
private ContentProviderClient mMediaProviderClient;
private SurfaceHolder mSurfaceHolder = null;
private ShutterButton mShutterButton;
@@ -378,7 +377,10 @@
mPreviewFrame = findViewById(R.id.camera_preview);
mPreviewFrame.setOnTouchListener(this);
mFocusIndicator = (RotateLayout) findViewById(R.id.focus_indicator_rotate_layout);
- mFocusManager.initialize(mFocusIndicator, mPreviewFrame, mFaceView, this);
+ CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
+ boolean mirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT);
+ mFocusManager.initialize(mFocusIndicator, mPreviewFrame, mFaceView, this,
+ mirror, mDisplayOrientation);
mFocusManager.initializeSoundPlayer(getResources().openRawResourceFd(R.raw.camera_focus));
mImageSaver = new ImageSaver();
Util.initializeScreenBrightness(getWindow(), getContentResolver());
@@ -1441,11 +1443,11 @@
}
@Override
- protected void onResume() {
- super.onResume();
- mPausing = false;
+ protected void doOnResume() {
if (mOpenCameraFail || mCameraDisabled) return;
+ mPausing = false;
+
mJpegPictureCallbackTime = 0;
mZoomValue = 0;
diff --git a/src/com/android/camera/EffectsRecorder.java b/src/com/android/camera/EffectsRecorder.java
index 7c81bf0..d3b277d 100644
--- a/src/com/android/camera/EffectsRecorder.java
+++ b/src/com/android/camera/EffectsRecorder.java
@@ -112,9 +112,10 @@
private static final int STATE_CONFIGURE = 0;
private static final int STATE_WAITING_FOR_SURFACE = 1;
- private static final int STATE_PREVIEW = 2;
- private static final int STATE_RECORD = 3;
- private static final int STATE_RELEASED = 4;
+ private static final int STATE_STARTING_PREVIEW = 2;
+ private static final int STATE_PREVIEW = 3;
+ private static final int STATE_RECORD = 4;
+ private static final int STATE_RELEASED = 5;
private int mState = STATE_CONFIGURE;
private boolean mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE);
@@ -287,6 +288,7 @@
case STATE_WAITING_FOR_SURFACE:
startPreview();
break;
+ case STATE_STARTING_PREVIEW:
case STATE_PREVIEW:
initializeEffect(true);
break;
@@ -309,7 +311,8 @@
mEffect = effect;
mEffectParameter = effectParameter;
- if (mState == STATE_PREVIEW) {
+ if (mState == STATE_PREVIEW ||
+ mState == STATE_STARTING_PREVIEW) {
initializeEffect(false);
}
}
@@ -334,7 +337,8 @@
}
private void setRecordingOrientation() {
- if ( mState <= STATE_PREVIEW && mRunner != null ) {
+ if ( (mState == STATE_CONFIGURE || mState == STATE_WAITING_FOR_SURFACE)
+ && mRunner != null ) {
Point bl = new Point(0, 0);
Point br = new Point(1, 0);
Point tl = new Point(0, 1);
@@ -443,7 +447,8 @@
"previewWidth", mPreviewWidth,
"previewHeight", mPreviewHeight,
"orientation", mOrientationHint);
- if (mState == STATE_PREVIEW) {
+ if (mState == STATE_PREVIEW ||
+ mState == STATE_STARTING_PREVIEW) {
// Switching effects while running. Inform video camera.
sendMessage(mCurrentEffect, EFFECT_MSG_SWITCHING_EFFECT);
}
@@ -468,7 +473,8 @@
Log.v(TAG, "New runner: " + mRunner
+ ". Old runner: " + mOldRunner);
}
- if (mState == STATE_PREVIEW) {
+ if (mState == STATE_PREVIEW ||
+ mState == STATE_STARTING_PREVIEW) {
// Switching effects while running. Stop existing runner.
// The stop callback will take care of starting new runner.
mCameraDevice.stopPreview();
@@ -505,6 +511,7 @@
if (mLogVerbose) Log.v(TAG, "Starting preview (" + this + ")");
switch (mState) {
+ case STATE_STARTING_PREVIEW:
case STATE_PREVIEW:
// Already running preview
Log.w(TAG, "startPreview called when already running preview");
@@ -543,6 +550,7 @@
if (mLogVerbose) Log.v(TAG, "Starting filter graph");
+ mState = STATE_STARTING_PREVIEW;
mRunner.run();
// Rest of preview startup handled in mSourceReadyCallback
}
@@ -554,12 +562,26 @@
synchronized(EffectsRecorder.this) {
mTextureSource = source;
- // When shutting down a graph, we receive a null SurfaceTexture to
- // indicate that. Don't want to connect up the camera in that case.
- if (source == null) return;
-
if (mState == STATE_RELEASED) return;
+ if (source == null) {
+ if (mState == STATE_PREVIEW ||
+ mState == STATE_STARTING_PREVIEW ||
+ mState == STATE_RECORD) {
+ // A null source here means the graph is shutting down
+ // unexpectedly, so we need to turn off preview before
+ // the surface texture goes away.
+ mCameraDevice.stopPreview();
+ try {
+ mCameraDevice.setPreviewTexture(null);
+ } catch(IOException e) {
+ throw new RuntimeException("Unable to disconnect " +
+ "camera from effect input", e);
+ }
+ }
+ return;
+ }
+
// Lock AE/AWB to reduce transition flicker
tryEnable3ALocks(true);
@@ -667,6 +689,7 @@
switch (mState) {
case STATE_CONFIGURE:
+ case STATE_STARTING_PREVIEW:
case STATE_PREVIEW:
Log.w(TAG, "StopRecording called when recording not active!");
return;
@@ -780,7 +803,8 @@
}
mOldRunner = null;
}
- if (mState == STATE_PREVIEW) {
+ if (mState == STATE_PREVIEW ||
+ mState == STATE_STARTING_PREVIEW) {
// Switching effects, start up the new runner
if (mLogVerbose) Log.v(TAG, "Previous effect halted, starting new effect.");
tryEnable3ALocks(false);
@@ -803,6 +827,7 @@
switch (mState) {
case STATE_RECORD:
+ case STATE_STARTING_PREVIEW:
case STATE_PREVIEW:
stopPreview();
// Fall-through
diff --git a/src/com/android/camera/FocusManager.java b/src/com/android/camera/FocusManager.java
index 228e2d1..86b92c2 100644
--- a/src/com/android/camera/FocusManager.java
+++ b/src/com/android/camera/FocusManager.java
@@ -21,7 +21,9 @@
import com.android.camera.ui.FocusIndicatorView;
import android.content.res.AssetFileDescriptor;
+import android.graphics.Matrix;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.hardware.Camera.Area;
import android.hardware.Camera.Parameters;
import android.os.Handler;
@@ -57,6 +59,7 @@
private boolean mInLongPress;
private boolean mLockAeAwbNeeded;
private boolean mAeAwbLock;
+ private Matrix mMatrix;
private SoundPlayer mSoundPlayer;
private View mFocusIndicatorRotateLayout;
private FocusIndicatorView mFocusIndicator;
@@ -98,6 +101,7 @@
mPreferences = preferences;
mDefaultFocusMode = defaultFocusMode;
mHandler = new MainHandler();
+ mMatrix = new Matrix();
}
// This has to be initialized before initialize().
@@ -111,13 +115,22 @@
}
public void initialize(View focusIndicatorRotate, View previewFrame,
- FaceView faceView, Listener listener) {
+ FaceView faceView, Listener listener, boolean mirror, int displayOrientation) {
mFocusIndicatorRotateLayout = focusIndicatorRotate;
mFocusIndicator = (FocusIndicatorView) focusIndicatorRotate.findViewById(
R.id.focus_indicator);
mPreviewFrame = previewFrame;
mFaceView = faceView;
mListener = listener;
+
+ Matrix matrix = new Matrix();
+ Util.prepareMatrix(matrix, mirror, displayOrientation,
+ previewFrame.getWidth(), previewFrame.getHeight());
+ // In face detection, the matrix converts the driver coordinates to UI
+ // coordinates. In tap focus, the inverted matrix converts the UI
+ // coordinates to driver coordinates.
+ matrix.invert(mMatrix);
+
if (mParameters != null) {
mInitialized = true;
} else {
@@ -270,9 +283,9 @@
// Convert the coordinates to driver format.
// AE area is bigger because exposure is sensitive and
// easy to over- or underexposure if area is too small.
- calculateTapArea(focusWidth, focusHeight, 1, x, y, previewWidth, previewHeight,
+ calculateTapArea(focusWidth, focusHeight, 1f, x, y, previewWidth, previewHeight,
mFocusArea.get(0).rect);
- calculateTapArea(focusWidth, focusHeight, 1.5, x, y, previewWidth, previewHeight,
+ calculateTapArea(focusWidth, focusHeight, 1.5f, x, y, previewWidth, previewHeight,
mMeteringArea.get(0).rect);
// Use margin to set the focus indicator to the touched area.
@@ -451,23 +464,16 @@
mMeteringArea = null;
}
- public void calculateTapArea(int focusWidth, int focusHeight, double areaMultiple,
+ public void calculateTapArea(int focusWidth, int focusHeight, float areaMultiple,
int x, int y, int previewWidth, int previewHeight, Rect rect) {
int areaWidth = (int)(focusWidth * areaMultiple);
int areaHeight = (int)(focusHeight * areaMultiple);
- int areaLeft = Util.clamp(x - areaWidth / 2, 0, previewWidth - areaWidth);
- int areaTop = Util.clamp(y - areaHeight / 2, 0, previewHeight - areaHeight);
- convertToFocusArea(areaLeft, areaTop, areaWidth, areaHeight, previewWidth, previewHeight,
- rect);
- }
+ int left = Util.clamp(x - areaWidth / 2, 0, previewWidth - areaWidth);
+ int top = Util.clamp(y - areaHeight / 2, 0, previewHeight - areaHeight);
- // Convert the touch point to the focus area in driver format.
- public static void convertToFocusArea(int left, int top, int focusWidth, int focusHeight,
- int previewWidth, int previewHeight, Rect rect) {
- rect.left = Math.round((float) left / previewWidth * 2000 - 1000);
- rect.top = Math.round((float) top / previewHeight * 2000 - 1000);
- rect.right = Math.round((float) (left + focusWidth) / previewWidth * 2000 - 1000);
- rect.bottom = Math.round((float) (top + focusHeight) / previewHeight * 2000 - 1000);
+ RectF rectF = new RectF(left, top, left + areaWidth, top + areaHeight);
+ mMatrix.mapRect(rectF);
+ Util.rectFToRect(rectF, rect);
}
public boolean isFocusCompleted() {
diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java
index 31a54d5..4c28e56 100644
--- a/src/com/android/camera/Util.java
+++ b/src/com/android/camera/Util.java
@@ -27,6 +27,8 @@
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.RectF;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
@@ -522,6 +524,18 @@
}
}
+ public static void dumpRect(RectF rect, String msg) {
+ Log.v(TAG, msg + "=(" + rect.left + "," + rect.top
+ + "," + rect.right + "," + rect.bottom + ")");
+ }
+
+ public static void rectFToRect(RectF rectF, Rect rect) {
+ rect.left = Math.round(rectF.left);
+ rect.top = Math.round(rectF.top);
+ rect.right = Math.round(rectF.right);
+ rect.bottom = Math.round(rectF.bottom);
+ }
+
public static void prepareMatrix(Matrix matrix, boolean mirror, int displayOrientation,
int viewWidth, int viewHeight) {
// Need mirror for front camera.
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index 4694c90..5ad9205 100755
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -134,7 +134,6 @@
private static final String EFFECT_BG_FROM_GALLERY = "gallery";
- private android.hardware.Camera mCameraDevice;
private final CameraErrorCallback mErrorCallback = new CameraErrorCallback();
private ComboPreferences mPreferences;
@@ -785,10 +784,10 @@
}
@Override
- protected void onResume() {
- super.onResume();
- mPausing = false;
+ protected void doOnResume() {
if (mOpenCameraFail || mCameraDisabled) return;
+
+ mPausing = false;
mZoomValue = 0;
showVideoSnapshotUI(false);
diff --git a/src/com/android/camera/panorama/MosaicFrameProcessor.java b/src/com/android/camera/panorama/MosaicFrameProcessor.java
index 300e4e3..6c70b19 100644
--- a/src/com/android/camera/panorama/MosaicFrameProcessor.java
+++ b/src/com/android/camera/panorama/MosaicFrameProcessor.java
@@ -91,8 +91,10 @@
}
public void clear() {
- mIsMosaicMemoryAllocated = false;
- mMosaicer.freeMosaicMemory();
+ if (mIsMosaicMemoryAllocated) {
+ mIsMosaicMemoryAllocated = false;
+ mMosaicer.freeMosaicMemory();
+ }
}
public void setStripType(int type) {
diff --git a/src/com/android/camera/panorama/PanoramaActivity.java b/src/com/android/camera/panorama/PanoramaActivity.java
index 0e055e5..43d33a8 100755
--- a/src/com/android/camera/panorama/PanoramaActivity.java
+++ b/src/com/android/camera/panorama/PanoramaActivity.java
@@ -144,7 +144,6 @@
private int mPreviewWidth;
private int mPreviewHeight;
- private Camera mCameraDevice;
private int mCameraState;
private int mCaptureState;
private SensorManager mSensorManager;
@@ -916,9 +915,7 @@
}
@Override
- protected void onResume() {
- super.onResume();
-
+ protected void doOnResume() {
mPausing = false;
mOrientationEventListener.enable();
diff --git a/src/com/android/camera/ui/FaceView.java b/src/com/android/camera/ui/FaceView.java
index 167d8b9..9018886 100644
--- a/src/com/android/camera/ui/FaceView.java
+++ b/src/com/android/camera/ui/FaceView.java
@@ -117,17 +117,11 @@
mPause = false;
}
- private void dumpRect(RectF rect, String msg) {
- Log.v(TAG, msg + "=(" + rect.left + "," + rect.top
- + "," + rect.right + "," + rect.bottom + ")");
- }
-
@Override
protected void onDraw(Canvas canvas) {
if (mFaces != null && mFaces.length > 0) {
// Prepare the matrix.
- Util.prepareMatrix(mMatrix, mMirror, mDisplayOrientation, getWidth(),
- getHeight());
+ Util.prepareMatrix(mMatrix, mMirror, mDisplayOrientation, getWidth(), getHeight());
// Focus indicator is directional. Rotate the matrix and the canvas
// so it looks correctly in all orientations.
@@ -137,9 +131,9 @@
for (int i = 0; i < mFaces.length; i++) {
// Transform the coordinates.
mRect.set(mFaces[i].rect);
- if (LOGV) dumpRect(mRect, "Original rect");
+ if (LOGV) Util.dumpRect(mRect, "Original rect");
mMatrix.mapRect(mRect);
- if (LOGV) dumpRect(mRect, "Transformed rect");
+ if (LOGV) Util.dumpRect(mRect, "Transformed rect");
mFaceIndicator.setBounds(Math.round(mRect.left), Math.round(mRect.top),
Math.round(mRect.right), Math.round(mRect.bottom));
diff --git a/tests/src/com/android/camera/unittest/CameraTest.java b/tests/src/com/android/camera/unittest/CameraTest.java
index ad0eed5..0e1242c 100644
--- a/tests/src/com/android/camera/unittest/CameraTest.java
+++ b/tests/src/com/android/camera/unittest/CameraTest.java
@@ -73,22 +73,6 @@
assertEquals(180, Util.roundOrientation(180, 270));
}
- public void testConvertToFocusArea() {
- Rect rect = new Rect();
- FocusManager.convertToFocusArea(0, 0, 100, 100, 800, 480, rect);
- assertEquals(new Rect(-1000, -1000, -750, -583), rect);
- FocusManager.convertToFocusArea(0, 0, 400, 240, 800, 480, rect);
- assertEquals(new Rect(-1000, -1000, 0, 0), rect);
- FocusManager.convertToFocusArea(400, 240, 400, 240, 800, 480, rect);
- assertEquals(new Rect(0, 0, 1000, 1000), rect);
- FocusManager.convertToFocusArea(200, 120, 400, 240, 800, 480, rect);
- assertEquals(new Rect(-500, -500, 500, 500), rect);
- FocusManager.convertToFocusArea(0, 0, 800, 480, 800, 480, rect);
- assertEquals(new Rect(-1000, -1000, 1000, 1000), rect);
- FocusManager.convertToFocusArea(860, 620, 100, 100, 960, 720, rect);
- assertEquals(new Rect(792, 722, 1000, 1000), rect);
- }
-
public void testPrepareMatrix() {
Matrix matrix = new Matrix();
float[] points;