summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorRuben Brunk <rubenbrunk@google.com>2015-02-05 19:54:36 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-02-05 19:54:37 +0000
commitcd0d7cdefef0dbf395e5b159dccb6e884a2077b7 (patch)
treee43c3d6ed53584e141a7aaff365ef9110f633e3a /core
parent967439b4d1151a613058b1439e1e4240cdef28d9 (diff)
parente3c0434d9741c78ef0405de3e9f4d16b6a8ef360 (diff)
downloadframeworks_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.java60
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()));
+ }
}
}