diff options
author | Ruben Brunk <rubenbrunk@google.com> | 2015-02-05 19:54:36 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-02-05 19:54:37 +0000 |
commit | cd0d7cdefef0dbf395e5b159dccb6e884a2077b7 (patch) | |
tree | e43c3d6ed53584e141a7aaff365ef9110f633e3a /core | |
parent | 967439b4d1151a613058b1439e1e4240cdef28d9 (diff) | |
parent | e3c0434d9741c78ef0405de3e9f4d16b6a8ef360 (diff) | |
download | frameworks_base-cd0d7cdefef0dbf395e5b159dccb6e884a2077b7.zip frameworks_base-cd0d7cdefef0dbf395e5b159dccb6e884a2077b7.tar.gz frameworks_base-cd0d7cdefef0dbf395e5b159dccb6e884a2077b7.tar.bz2 |
Merge "camera2: Make legacy error handling more robust." into lmp-mr1-dev
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/hardware/camera2/legacy/RequestThreadManager.java | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java index 6535a4e..f1f2f0c 100644 --- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java @@ -44,6 +44,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import static com.android.internal.util.Preconditions.*; @@ -68,7 +69,7 @@ public class RequestThreadManager { // For slightly more spammy messages that will get repeated every frame private static final boolean VERBOSE = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.VERBOSE); - private final Camera mCamera; + private Camera mCamera; private final CameraCharacteristics mCharacteristics; private final CameraDeviceState mDeviceState; @@ -83,8 +84,8 @@ public class RequestThreadManager { private static final int MAX_IN_FLIGHT_REQUESTS = 2; private static final int PREVIEW_FRAME_TIMEOUT = 1000; // ms - private static final int JPEG_FRAME_TIMEOUT = 3000; // ms (same as CTS for API2) - private static final int REQUEST_COMPLETE_TIMEOUT = 3000; // ms (same as JPEG timeout) + private static final int JPEG_FRAME_TIMEOUT = 4000; // ms (same as CTS for API2) + private static final int REQUEST_COMPLETE_TIMEOUT = JPEG_FRAME_TIMEOUT; // ms (same as JPEG timeout) private static final float ASPECT_RATIO_TOLERANCE = 0.01f; private boolean mPreviewRunning = false; @@ -108,6 +109,8 @@ public class RequestThreadManager { private final FpsCounter mPrevCounter = new FpsCounter("Incoming Preview"); private final FpsCounter mRequestCounter = new FpsCounter("Incoming Requests"); + private final AtomicBoolean mQuit = new AtomicBoolean(false); + // Stuff JPEGs into HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers to get around SW write // limitations for (b/17379185). private static final boolean USE_BLOB_FORMAT_OVERRIDE = true; @@ -325,7 +328,15 @@ public class RequestThreadManager { Log.d(TAG, "configureOutputs with " + outputsStr); } - stopPreview(); + try { + stopPreview(); + } catch (RuntimeException e) { + Log.e(TAG, "Received device exception in configure call: ", e); + mDeviceState.setError( + CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); + return; + } + /* * Try to release the previous preview's surface texture earlier if we end up * using a different one; this also reduces the likelihood of getting into a deadlock @@ -335,6 +346,11 @@ public class RequestThreadManager { mCamera.setPreviewTexture(/*surfaceTexture*/null); } catch (IOException e) { Log.w(TAG, "Failed to clear prior SurfaceTexture, may cause GL deadlock: ", e); + } catch (RuntimeException e) { + Log.e(TAG, "Received device exception in configure call: ", e); + mDeviceState.setError( + CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); + return; } if (mGLThreadManager != null) { @@ -470,7 +486,14 @@ public class RequestThreadManager { mPreviewTexture.setOnFrameAvailableListener(mPreviewCallback); } - mCamera.setParameters(mParams); + try { + mCamera.setParameters(mParams); + } catch (RuntimeException e) { + Log.e(TAG, "Received device exception while configuring: ", e); + mDeviceState.setError( + CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); + + } } private void resetJpegSurfaceFormats(Collection<Surface> surfaces) { @@ -793,7 +816,7 @@ public class RequestThreadManager { } } catch (IOException e) { - Log.e(TAG, "Received device exception: ", e); + Log.e(TAG, "Received device exception during capture call: ", e); mDeviceState.setError( CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); break; @@ -802,6 +825,11 @@ public class RequestThreadManager { mDeviceState.setError( CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); break; + } catch (RuntimeException e) { + Log.e(TAG, "Received device exception during capture call: ", e); + mDeviceState.setError( + CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE); + break; } if (paramsChanged) { @@ -878,9 +906,11 @@ public class RequestThreadManager { } if (mGLThreadManager != null) { mGLThreadManager.quit(); + mGLThreadManager = null; } if (mCamera != null) { mCamera.release(); + mCamera = null; } resetJpegSurfaceFormats(mCallbackOutputs); break; @@ -942,14 +972,16 @@ public class RequestThreadManager { * Quit the request thread, and clean up everything. */ public void quit() { - Handler handler = mRequestThread.waitAndGetHandler(); - handler.sendMessageAtFrontOfQueue(handler.obtainMessage(MSG_CLEANUP)); - mRequestThread.quitSafely(); - try { - mRequestThread.join(); - } catch (InterruptedException e) { - Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.", - mRequestThread.getName(), mRequestThread.getId())); + if (!mQuit.getAndSet(true)) { // Avoid sending messages on dead thread's handler. + Handler handler = mRequestThread.waitAndGetHandler(); + handler.sendMessageAtFrontOfQueue(handler.obtainMessage(MSG_CLEANUP)); + mRequestThread.quitSafely(); + try { + mRequestThread.join(); + } catch (InterruptedException e) { + Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.", + mRequestThread.getName(), mRequestThread.getId())); + } } } |