diff options
author | Sai Kumar Sanagavarapu <ssanagav@codeaurora.org> | 2014-07-02 11:59:05 +0530 |
---|---|---|
committer | Abhisek Devkota <ciwrl@cyanogenmod.com> | 2014-10-20 22:19:31 +0000 |
commit | 9ca415b446d5f79876fd2e3d5847f6191494a92b (patch) | |
tree | e0ff9dc9c21b3bb70fc024f3220f755dc7477400 | |
parent | 77468c1418c7b164b195b84e478778049c52547e (diff) | |
download | android_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.java | 3 | ||||
-rw-r--r-- | src/com/android/camera/PhotoController.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/PhotoModule.java | 149 | ||||
-rw-r--r-- | src/com/android/camera/PhotoUI.java | 10 |
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) { |