summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSai Kumar Sanagavarapu <ssanagav@codeaurora.org>2014-07-02 11:59:05 +0530
committerAbhisek Devkota <ciwrl@cyanogenmod.com>2014-10-20 22:19:31 +0000
commit9ca415b446d5f79876fd2e3d5847f6191494a92b (patch)
treee0ff9dc9c21b3bb70fc024f3220f755dc7477400
parent77468c1418c7b164b195b84e478778049c52547e (diff)
downloadandroid_packages_apps_Camera2-9ca415b446d5f79876fd2e3d5847f6191494a92b.tar.gz
android_packages_apps_Camera2-9ca415b446d5f79876fd2e3d5847f6191494a92b.tar.bz2
android_packages_apps_Camera2-9ca415b446d5f79876fd2e3d5847f6191494a92b.zip
Camera: open Camera and start Preview in a seperate thread.
Start openCamera and start preview in a separate thread so that UI initialization and preview can run parallely. This is to improve camera cold start latency. Change-Id: I57af45bc90a4db1630c73449d543c3ff0992e55c
-rw-r--r--src/com/android/camera/CameraActivity.java3
-rw-r--r--src/com/android/camera/PhotoController.java2
-rw-r--r--src/com/android/camera/PhotoModule.java149
-rw-r--r--src/com/android/camera/PhotoUI.java10
4 files changed, 107 insertions, 57 deletions
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 17d69794b..327052251 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -183,6 +183,7 @@ public class CameraActivity extends Activity
private ViewGroup mUndoDeletionBar;
private boolean mIsUndoingDeletion = false;
private boolean mIsEditActivityInProgress = false;
+ protected boolean mIsModuleSwitchInProgress = false;
private Uri[] mNfcPushUris = new Uri[1];
@@ -1465,6 +1466,7 @@ public class CameraActivity extends Activity
return;
}
+ mIsModuleSwitchInProgress = true;
CameraHolder.instance().keep();
closeModule(mCurrentModule);
setModuleFromIndex(moduleIndex);
@@ -1479,6 +1481,7 @@ public class CameraActivity extends Activity
// starts up.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().putInt(CameraSettings.KEY_STARTUP_MODULE_INDEX, moduleIndex).apply();
+ mIsModuleSwitchInProgress = false;
}
/**
diff --git a/src/com/android/camera/PhotoController.java b/src/com/android/camera/PhotoController.java
index c1c3a8562..b08f8c088 100644
--- a/src/com/android/camera/PhotoController.java
+++ b/src/com/android/camera/PhotoController.java
@@ -23,7 +23,7 @@ import com.android.camera.ShutterButton.OnShutterButtonListener;
public interface PhotoController extends OnShutterButtonListener {
-
+ public static final int INIT = -1;
public static final int PREVIEW_STOPPED = 0;
public static final int IDLE = 1; // preview is active
// Focus is in progress. The exact focus state is in Focus.java.
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 3843ed4ae..75e17a351 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -135,6 +135,7 @@ public class PhotoModule
private static final int SET_PHOTO_UI_PARAMS = 12;
private static final int SWITCH_TO_GCAM_MODULE = 13;
private static final int CONFIGURE_SKIN_TONE_FACTOR = 14;
+ private static final int ON_PREVIEW_STARTED = 15;
private static final int UPDATE_ASD_ICON = 16;
private static final int CLEAR_ASD_ICON = 17;
@@ -227,6 +228,15 @@ public class PhotoModule
}
};
+ private class OpenCameraThread extends Thread {
+ @Override
+ public void run() {
+ openCamera();
+ startPreview();
+ }
+ }
+
+ private OpenCameraThread mOpenCameraThread = null;
/**
* An unpublished intent flag requesting to return as soon as capturing
* is completed.
@@ -250,7 +260,7 @@ public class PhotoModule
private boolean mFirstTimeInitialized;
private boolean mIsImageCaptureIntent;
- private int mCameraState = PREVIEW_STOPPED;
+ private int mCameraState = INIT;
private boolean mSnapshotOnIdle = false;
private ContentResolver mContentResolver;
@@ -454,6 +464,10 @@ public class PhotoModule
}
break;
}
+ case ON_PREVIEW_STARTED: {
+ onPreviewStarted();
+ break;
+ }
case UPDATE_ASD_ICON: {
if (!mSceneDetection) {
mUI.updateSceneDetectionIcon(null);
@@ -481,7 +495,6 @@ public class PhotoModule
public void init(CameraActivity activity, View parent) {
mActivity = activity;
mRootView = parent;
- mUI = new PhotoUI(activity, this, parent);
mPreferences = new ComboPreferences(mActivity);
CameraSettings.upgradeGlobalPreferences(mPreferences.getGlobal());
mCameraId = getPreferredCameraId(mPreferences);
@@ -503,9 +516,11 @@ public class PhotoModule
// Power shutter
mActivity.initPowerShutter(mPreferences);
- // we need to reset exposure for the preview
- resetExposureCompensation();
-
+ if (mOpenCameraThread == null && !mActivity.mIsModuleSwitchInProgress) {
+ mOpenCameraThread = new OpenCameraThread();
+ mOpenCameraThread.start();
+ }
+ mUI = new PhotoUI(activity, this, parent);
initializeControlByIntent();
mQuickCapture = mActivity.getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
mLocationManager = new LocationManager(mActivity, mUI);
@@ -530,6 +545,7 @@ public class PhotoModule
private void onPreviewStarted() {
setCameraState(IDLE);
+ mFocusManager.onPreviewStarted();
startFaceDetection();
locationFirstRun();
}
@@ -558,7 +574,20 @@ public class PhotoModule
@Override
public void onPreviewUIReady() {
- startPreview();
+ if (mPaused || mCameraDevice == null) {
+ return;
+ }
+ Log.v(TAG, "onPreviewUIReady");
+ if (mCameraState == PREVIEW_STOPPED) {
+ startPreview();
+ } else {
+ SurfaceTexture st = mUI.getSurfaceTexture();
+ if (st == null) {
+ Log.w(TAG, "startPreview: surfaceTexture is not ready.");
+ return;
+ }
+ mCameraDevice.setPreviewTexture(st);
+ }
}
@Override
@@ -566,6 +595,7 @@ public class PhotoModule
if (mCameraDevice == null) {
return;
}
+ Log.v(TAG, "onPreviewUIDestroyed");
stopPreview();
mCameraDevice.setPreviewTexture(null);
}
@@ -580,12 +610,10 @@ public class PhotoModule
}
private void onCameraOpened() {
- View root = mUI.getRootView();
- // These depend on camera parameters.
-
- int width = root.getWidth();
- int height = root.getHeight();
- mFocusManager.setPreviewSize(width, height);
+ if (mPaused) {
+ return;
+ }
+ Log.v(TAG, "onCameraOpened");
openCameraCommon();
resizeForPreviewAspectRatio();
}
@@ -617,6 +645,7 @@ public class PhotoModule
return;
}
mParameters = mCameraDevice.getParameters();
+ mInitialParams = mParameters;
initializeCapabilities();
CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
mMirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT);
@@ -650,8 +679,6 @@ public class PhotoModule
}
updateSceneMode();
showTapToFocusToastIfNeeded();
-
-
}
@Override
@@ -743,8 +770,6 @@ public class PhotoModule
mFirstTimeInitialized = true;
Log.d(TAG, "addIdleHandler in first time initialization");
addIdleHandler();
-
- mActivity.updateStorageSpaceAndHint();
}
// If the activity is paused and resumed, this method will be called in
@@ -800,6 +825,8 @@ public class PhotoModule
@Override
public void startFaceDetection() {
+ if (mCameraDevice == null) return;
+
if (mFaceDetectionEnabled == false
|| mFaceDetectionStarted || mCameraState != IDLE) return;
if (mParameters.getMaxNumDetectedFaces() > 0) {
@@ -1527,7 +1554,8 @@ public class PhotoModule
if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) return;
int oldOrientation = mOrientation;
mOrientation = CameraUtil.roundOrientation(orientation, mOrientation);
- if (oldOrientation != mOrientation) {
+ if (oldOrientation != mOrientation &&
+ oldOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
Log.v(TAG, "onOrientationChanged, update parameters");
if (mParameters != null && mCameraDevice != null) {
onSharedPreferenceChanged();
@@ -1786,28 +1814,28 @@ public class PhotoModule
mPaused = false;
}
- private boolean prepareCamera() {
+ private void openCamera() {
// We need to check whether the activity is paused before long
// operations to ensure that onPause() can be done ASAP.
+ if (mPaused) {
+ return;
+ }
Log.v(TAG, "Open camera device.");
mCameraDevice = CameraUtil.openCamera(
mActivity, mCameraId, mHandler,
mActivity.getCameraOpenErrorCallback());
if (mCameraDevice == null) {
Log.e(TAG, "Failed to open camera:" + mCameraId);
- return false;
+ mHandler.sendEmptyMessage(OPEN_CAMERA_FAIL);
+ return;
}
mParameters = mCameraDevice.getParameters();
-
- initializeCapabilities();
- if (mFocusManager == null) initializeFocusManager();
- setCameraParameters(UPDATE_PARAM_ALL);
- mHandler.sendEmptyMessage(CAMERA_OPEN_DONE);
mCameraPreviewParamsReady = true;
- startPreview();
- mOnResumeTime = SystemClock.uptimeMillis();
- checkDisplayRotation();
- return true;
+ mInitialParams = mParameters;
+ if (mFocusManager == null) initializeFocusManager();
+ initializeCapabilities();
+ mHandler.sendEmptyMessageDelayed(CAMERA_OPEN_DONE,100);
+ return;
}
@Override
@@ -1836,13 +1864,14 @@ public class PhotoModule
Log.v(TAG, "Executing onResumeTasks.");
if (mOpenCameraFail || mCameraDisabled) return;
+ if (mOpenCameraThread == null) {
+ mOpenCameraThread = new OpenCameraThread();
+ mOpenCameraThread.start();
+ }
+
mJpegPictureCallbackTime = 0;
mZoomValue = 0;
resetExposureCompensation();
- if (!prepareCamera()) {
- // Camera failure.
- return;
- }
if (mSkinToneSeekBar != true)
{
@@ -1858,6 +1887,8 @@ public class PhotoModule
}
mUI.initDisplayChangeListener();
keepScreenOnAwhile();
+ mUI.updateOnScreenIndicators(mParameters, mPreferenceGroup,
+ mPreferences);
UsageStatistics.onContentViewChanged(
UsageStatistics.COMPONENT_CAMERA, "PhotoModule");
@@ -1871,6 +1902,9 @@ public class PhotoModule
if (msensor != null) {
mSensorManager.registerListener(this, msensor, SensorManager.SENSOR_DELAY_NORMAL);
}
+
+ mOnResumeTime = SystemClock.uptimeMillis();
+ checkDisplayRotation();
}
@Override
@@ -1895,6 +1929,14 @@ public class PhotoModule
Log.v(TAG, "On pause.");
mUI.showPreviewCover();
+ try {
+ if (mOpenCameraThread != null) {
+ mOpenCameraThread.join();
+ }
+ } catch (InterruptedException ex) {
+ // ignore
+ }
+ mOpenCameraThread = null;
// Reset the focus first. Camera CTS does not guarantee that
// cancelAutoFocus is allowed after preview stops.
if (mCameraDevice != null && mCameraState != PREVIEW_STOPPED) {
@@ -1952,6 +1994,12 @@ public class PhotoModule
mInitialParams, this, mMirror,
mActivity.getMainLooper(), mUI);
}
+ View root = mUI.getRootView();
+ // These depend on camera parameters.
+
+ int width = root.getWidth();
+ int height = root.getHeight();
+ mFocusManager.setPreviewSize(width, height);
}
@Override
@@ -2141,7 +2189,9 @@ public class PhotoModule
mFaceDetectionStarted = false;
mCameraDevice = null;
setCameraState(PREVIEW_STOPPED);
- mFocusManager.onCameraReleased();
+ if (mFocusManager != null) {
+ mFocusManager.onCameraReleased();
+ }
}
}
@@ -2165,19 +2215,17 @@ public class PhotoModule
startPreview();
}
- /** This can run on a background thread, post any view updates to MainHandler. */
+ /** This can run on a background thread, so don't do UI updates here. Post any
+ view updates to MainHandler or do it on onPreviewStarted() . */
private void startPreview() {
if (mPaused || mCameraDevice == null) {
return;
}
- // Any decisions we make based on the surface texture state
- // need to be protected.
+ Log.v(TAG, "startPreview");
+
SurfaceTexture st = mUI.getSurfaceTexture();
- if (st == null) {
- Log.w(TAG, "startPreview: surfaceTexture is not ready.");
- return;
- }
+ mCameraDevice.setPreviewTexture(st);
if (!mCameraPreviewParamsReady) {
Log.w(TAG, "startPreview: parameters for preview is not ready.");
@@ -2186,11 +2234,16 @@ public class PhotoModule
mCameraDevice.setErrorCallback(mErrorCallback);
// Preview needs to be stopped when changing resolution
- if (mRestartPreview && mCameraState != PREVIEW_STOPPED) {
+ if (mRestartPreview && mCameraState != PREVIEW_STOPPED && mCameraState != INIT) {
stopPreview();
mRestartPreview = false;
}
+ setCameraParameters(UPDATE_PARAM_ALL);
+
+ mCameraDevice.startPreview();
+ mHandler.sendEmptyMessage(ON_PREVIEW_STARTED);
+
setDisplayOrientation();
if (!mSnapshotOnIdle) {
@@ -2203,10 +2256,6 @@ public class PhotoModule
}
}
mFocusManager.setAeAwbLock(false); // Unlock AE and AWB.
- }
- setCameraParameters(UPDATE_PARAM_ALL);
- // Let UI set its expected aspect ratio
- mCameraDevice.setPreviewTexture(st);
// Callback for automatic scene detection, if supported.
// Will run on UI thread
@@ -2215,16 +2264,11 @@ public class PhotoModule
mCameraDevice.setMetadataCallback(mHandler, mASDCallback);
}
- Log.v(TAG, "startPreview");
- mCameraDevice.startPreview();
- mFocusManager.onPreviewStarted();
- onPreviewStarted();
-
// Set camera mode
CameraSettings.setVideoMode(mParameters, false);
mCameraDevice.setParameters(mParameters);
- if (mSnapshotOnIdle && mBurstShotsDone > 0) {
+ } else if (mBurstShotsDone > 0) {
mHandler.post(mDoSnapRunnable);
}
}
@@ -2302,6 +2346,7 @@ public class PhotoModule
return ret;
}
+ /** This can run on a background thread, so don't do UI updates here.*/
private void qcomUpdateCameraParametersPreference() {
// Set Picture Format
// Picture Formats specified in UI should be consistent with
@@ -2582,6 +2627,7 @@ public class PhotoModule
}
}
+ /** This can run on a background thread, so don't do UI updates here.*/
private boolean updateCameraParametersPreference() {
setAutoExposureLockIfSupported();
setAutoWhiteBalanceLockIfSupported();
@@ -2969,7 +3015,6 @@ public class PhotoModule
}
private void initializeCapabilities() {
- mInitialParams = mCameraDevice.getParameters();
mFocusAreaSupported = CameraUtil.isFocusAreaSupported(mInitialParams);
mMeteringAreaSupported = CameraUtil.isMeteringAreaSupported(mInitialParams);
mAeLockSupported = CameraUtil.isAutoExposureLockSupported(mInitialParams);
diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java
index c4260effb..8727271b3 100644
--- a/src/com/android/camera/PhotoUI.java
+++ b/src/com/android/camera/PhotoUI.java
@@ -292,10 +292,12 @@ public class PhotoUI implements PieListener,
ratio = 1 / ratio;
}
- Log.d(TAG,"setAspectRatio() ratio["+ratio+"] mAspectRatio["+mAspectRatio+"]");
- mAspectRatio = ratio;
- mAspectRatioResize = true;
- mTextureView.requestLayout();
+ if (mAspectRatio != ratio) {
+ Log.d(TAG,"setAspectRatio() ratio["+ratio+"] mAspectRatio["+mAspectRatio+"]");
+ mAspectRatio = ratio;
+ mAspectRatioResize = true;
+ mTextureView.requestLayout();
+ }
}
public void setSurfaceTextureSizeChangedListener(SurfaceTextureSizeChangedListener listener) {