From 210ba5c4da9391e06dbb9bf624783e747d192b04 Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Wed, 25 Jul 2018 16:47:40 -0700 Subject: [PATCH] Camera: Handle abandoned surface in finishConfiguration It's possible that surface for a stream goes away after cameraservice configures HAL stream, either during configure_streams or when session parameters are updated. In this case, do not put camera device in an error state. Test: Camera CTS, GCA Bug: 111581884 Change-Id: I7efc5aa22bc9b60ffaea23d8dae275f9a2bd026d --- .../device3/Camera3Device.cpp | 27 ++++++++++++++++--- .../device3/Camera3Stream.cpp | 9 ++++++- .../libcameraservice/device3/Camera3Stream.h | 1 + 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 543914e5a4..28ffc8b3db 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -2143,8 +2143,14 @@ status_t Camera3Device::setConsumerSurfaces(int streamId, res = stream->finishConfiguration(); if (res != OK) { - SET_ERR_L("Can't finish configuring output stream %d: %s (%d)", - stream->getId(), strerror(-res), res); + // If finishConfiguration fails due to abandoned surface, do not set + // device to error state. + bool isSurfaceAbandoned = + (res == NO_INIT || res == DEAD_OBJECT) && stream->isAbandoned(); + if (!isSurfaceAbandoned) { + SET_ERR_L("Can't finish configuring output stream %d: %s (%d)", + stream->getId(), strerror(-res), res); + } return res; } } @@ -2361,9 +2367,16 @@ bool Camera3Device::reconfigureCamera(const CameraMetadata& sessionParams) { //present streams end up with outstanding buffers that will //not get drained. internalUpdateStatusLocked(STATUS_ACTIVE); + } else if (rc == DEAD_OBJECT) { + // DEAD_OBJECT can be returned if either the consumer surface is + // abandoned, or the HAL has died. + // - If the HAL has died, configureStreamsLocked call will set + // device to error state, + // - If surface is abandoned, we should not set device to error + // state. + ALOGE("Failed to re-configure camera due to abandoned surface"); } else { - setErrorStateLocked("%s: Failed to re-configure camera: %d", - __FUNCTION__, rc); + SET_ERR_L("Failed to re-configure camera: %d", rc); } } else { ALOGE("%s: Failed to pause streaming: %d", __FUNCTION__, rc); @@ -2497,6 +2510,9 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode, CLOGE("Can't finish configuring input stream %d: %s (%d)", mInputStream->getId(), strerror(-res), res); cancelStreamsConfigurationLocked(); + if ((res == NO_INIT || res == DEAD_OBJECT) && mInputStream->isAbandoned()) { + return DEAD_OBJECT; + } return BAD_VALUE; } } @@ -2510,6 +2526,9 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode, CLOGE("Can't finish configuring output stream %d: %s (%d)", outputStream->getId(), strerror(-res), res); cancelStreamsConfigurationLocked(); + if ((res == NO_INIT || res == DEAD_OBJECT) && outputStream->isAbandoned()) { + return DEAD_OBJECT; + } return BAD_VALUE; } } diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp index 1105b754fa..6030d15f50 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.cpp +++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp @@ -331,7 +331,14 @@ status_t Camera3Stream::finishConfiguration() { status_t res; res = configureQueueLocked(); - if (res != OK) { + // configureQueueLocked could return error in case of abandoned surface. + // Treat as non-fatal error. + if (res == NO_INIT || res == DEAD_OBJECT) { + ALOGE("%s: Unable to configure stream %d queue (non-fatal): %s (%d)", + __FUNCTION__, mId, strerror(-res), res); + mState = STATE_ABANDONED; + return res; + } else if (res != OK) { ALOGE("%s: Unable to configure stream %d queue: %s (%d)", __FUNCTION__, mId, strerror(-res), res); mState = STATE_ERROR; diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h index a60cb56818..4ddcf1ab85 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.h +++ b/services/camera/libcameraservice/device3/Camera3Stream.h @@ -482,6 +482,7 @@ class Camera3Stream : // after the HAL has provided usage and max_buffers values. After this call, // the stream must be ready to produce all buffers for registration with // HAL. + // Returns NO_INIT or DEAD_OBJECT if the queue has been abandoned. virtual status_t configureQueueLocked() = 0; // Get the total number of buffers in the queue