diff options
| author | wenbinw <wenbinw@codeaurora.org> | 2013-08-14 20:09:02 +0800 |
|---|---|---|
| committer | Steve Kondik <shade@chemlab.org> | 2013-10-01 03:32:39 -0700 |
| commit | 593f1735c0d380b7be237fe468ad8f343d767935 (patch) | |
| tree | 737ef98970beaa795932cbb39f922545a51a93be | |
| parent | 2c0ca4deba9ecab07e4c26b470944810b4abf16a (diff) | |
| download | android_packages_apps_Gallery2-593f1735c0d380b7be237fe468ad8f343d767935.tar.gz android_packages_apps_Gallery2-593f1735c0d380b7be237fe468ad8f343d767935.tar.bz2 android_packages_apps_Gallery2-593f1735c0d380b7be237fe468ad8f343d767935.zip | |
Camera: Fix camcorder crash during pause and resume
When camcorder is suspended in background, if it receives resume
and pause event in very short interval, crash will happen.
After receiving resume event, the onresume method will be called,
and it will start another thread for starting preview. And soon,
the main thread receives pause event, the onpause method which will
close camera is called.
There will be a racing between the main thread and start preview
thread. If close camera get done first, crash will be observed.
To avoid the racing, the close camera operation should wait for the
start preview operation, and the join method is used here for
synchronization.
CRs-Fixed: 526007
Change-Id: Idf6a8660378bf1a65af1f5194a35d30822f1dcf6
| -rw-r--r-- | src/com/android/camera/CameraScreenNail.java | 9 | ||||
| -rw-r--r-- | src/com/android/camera/VideoModule.java | 59 |
2 files changed, 55 insertions, 13 deletions
diff --git a/src/com/android/camera/CameraScreenNail.java b/src/com/android/camera/CameraScreenNail.java index 993a7d336..b770a9a34 100644 --- a/src/com/android/camera/CameraScreenNail.java +++ b/src/com/android/camera/CameraScreenNail.java @@ -236,6 +236,15 @@ public class CameraScreenNail extends SurfaceTextureScreenNail { mListener.requestRender(); } + public void cancelAcquire() { + synchronized (mLock) { + if (mAcquireTexture) { + mAcquireTexture = false; + mLock.notifyAll(); + } + } + } + @Override public void releaseSurfaceTexture() { synchronized (mLock) { diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java index 7b5404468..6ce8cb331 100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -92,6 +92,7 @@ public class VideoModule implements CameraModule, private static final int SWITCH_CAMERA_START_ANIMATION = 9; private static final int HIDE_SURFACE_VIEW = 10; private static final int CAPTURE_ANIMATION_DONE = 11; + private static final int START_PREVIEW_DONE = 12; private static final int SCREEN_DELAY = 2 * 60 * 1000; @@ -192,6 +193,8 @@ public class VideoModule implements CameraModule, private int mVideoWidth; private int mVideoHeight; + private StartPreviewThread mStartPreviewThread; + private final MediaSaveService.OnMediaSavedListener mOnVideoSavedListener = new MediaSaveService.OnMediaSavedListener() { @Override @@ -223,6 +226,16 @@ public class VideoModule implements CameraModule, } } + private class StartPreviewThread extends Thread { + @Override + public void run() { + try { + startPreview(); + }catch (Exception e) { + } + } + } + private void openCamera() { try { synchronized(mCameraOpened) { @@ -305,6 +318,11 @@ public class VideoModule implements CameraModule, break; } + case START_PREVIEW_DONE: { + mStartPreviewThread = null; + break; + } + default: Log.v(TAG, "Unhandled message: " + msg.what); break; @@ -408,14 +426,16 @@ public class VideoModule implements CameraModule, // ignore } + CameraScreenNail screenNail = (CameraScreenNail) mActivity.mCameraScreenNail; + if (screenNail.getSurfaceTexture() == null) { + screenNail.acquireSurfaceTexture(); + } + readVideoPreferences(); mUI.setPrefChangedListener(this); - new Thread(new Runnable() { - @Override - public void run() { - startPreview(); - } - }).start(); + + mStartPreviewThread = new StartPreviewThread(); + mStartPreviewThread.start(); mQuickCapture = mActivity.getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false); mLocationManager = new LocationManager(mActivity, null); @@ -790,12 +810,14 @@ public class VideoModule implements CameraModule, } readVideoPreferences(); resizeForPreviewAspectRatio(); - new Thread(new Runnable() { - @Override - public void run() { - startPreview(); - } - }).start(); + + CameraScreenNail screenNail = (CameraScreenNail) mActivity.mCameraScreenNail; + screenNail.cancelAcquire(); + if (screenNail.getSurfaceTexture() == null) { + screenNail.acquireSurfaceTexture(); + } + mStartPreviewThread = new StartPreviewThread(); + mStartPreviewThread.start(); } else { // preview already started mUI.enableShutter(true); @@ -906,6 +928,7 @@ public class VideoModule implements CameraModule, private void onPreviewStarted() { mUI.enableShutter(true); + mHandler.sendEmptyMessage(START_PREVIEW_DONE); } @Override @@ -930,6 +953,16 @@ public class VideoModule implements CameraModule, // By default, we want to close the effects as well with the camera. private void closeCamera() { + CameraScreenNail screenNail = (CameraScreenNail) mActivity.mCameraScreenNail; + screenNail.cancelAcquire(); + try { + if (mStartPreviewThread != null) { + mStartPreviewThread.interrupt(); + mStartPreviewThread.join(); + mStartPreviewThread = null; + } + } catch (InterruptedException e) { + } closeCamera(true); } @@ -1929,7 +1962,7 @@ public class VideoModule implements CameraModule, mActivity.notifyScreenNailChanged(); } - if (screenNail.getSurfaceTexture() == null) { + if (mStartPreviewThread == null && screenNail.getSurfaceTexture() == null) { screenNail.acquireSurfaceTexture(); } } |
