Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73933788 authored by Yin-Chia Yeh's avatar Yin-Chia Yeh Committed by android-build-merger
Browse files

Merge "Camera: fix race in disconnect and deleteStream" into oc-dr1-dev

am: ef00a249

Change-Id: I4addf62e75478d8a2d9d707ed81974c5306998ed
parents 15fa2506 ef00a249
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ public:

    virtual binder::Status endConfigure(int operatingMode) override;

    // Returns -EBUSY if device is not idle
    // Returns -EBUSY if device is not idle or in error state
    virtual binder::Status deleteStream(int streamId) override;

    virtual binder::Status createStream(
+54 −3
Original line number Diff line number Diff line
@@ -315,6 +315,7 @@ status_t Camera3Device::disconnect() {
        mInterface->clear();
        mOutputStreams.clear();
        mInputStream.clear();
        mDeletedStreams.clear();
        mBufferManager.clear();
        internalUpdateStatusLocked(STATUS_UNINITIALIZED);
    }
@@ -1428,6 +1429,12 @@ status_t Camera3Device::deleteStream(int id) {
        return -EBUSY;
    }

    if (mStatus == STATUS_ERROR) {
        ALOGW("%s: Camera %s: deleteStream not allowed in ERROR state",
                __FUNCTION__, mId.string());
        return -EBUSY;
    }

    sp<Camera3StreamInterface> deletedStream;
    ssize_t outputStreamIdx = mOutputStreams.indexOfKey(id);
    if (mInputStream != NULL && id == mInputStream->getId()) {
@@ -2516,16 +2523,60 @@ void Camera3Device::flushInflightRequests() {
        streamBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
        streamBuffer.acquire_fence = -1;
        streamBuffer.release_fence = -1;

        // First check if the buffer belongs to deleted stream
        bool streamDeleted = false;
        for (auto& stream : mDeletedStreams) {
            if (streamId == stream->getId()) {
                streamDeleted = true;
                // Return buffer to deleted stream
                camera3_stream* halStream = stream->asHalStream();
                streamBuffer.stream = halStream;
                switch (halStream->stream_type) {
                    case CAMERA3_STREAM_OUTPUT:
                        res = stream->returnBuffer(streamBuffer, /*timestamp*/ 0);
                        if (res != OK) {
                            ALOGE("%s: Can't return output buffer for frame %d to"
                                  " stream %d: %s (%d)",  __FUNCTION__,
                                  frameNumber, streamId, strerror(-res), res);
                        }
                        break;
                    case CAMERA3_STREAM_INPUT:
                        res = stream->returnInputBuffer(streamBuffer);
                        if (res != OK) {
                            ALOGE("%s: Can't return input buffer for frame %d to"
                                  " stream %d: %s (%d)",  __FUNCTION__,
                                  frameNumber, streamId, strerror(-res), res);
                        }
                        break;
                    default: // Bi-direcitonal stream is deprecated
                        ALOGE("%s: stream %d has unknown stream type %d",
                                __FUNCTION__, streamId, halStream->stream_type);
                        break;
                }
                break;
            }
        }
        if (streamDeleted) {
            continue;
        }

        // Then check against configured streams
        if (streamId == inputStreamId) {
            streamBuffer.stream = mInputStream->asHalStream();
            res = mInputStream->returnInputBuffer(streamBuffer);
            if (res != OK) {
                ALOGE("%s: Can't return input buffer for frame %d to"
                      "  its stream:%s (%d)",  __FUNCTION__,
                      frameNumber, strerror(-res), res);
                      " stream %d: %s (%d)",  __FUNCTION__,
                      frameNumber, streamId, strerror(-res), res);
            }
        } else {
            streamBuffer.stream = mOutputStreams.valueFor(streamId)->asHalStream();
            ssize_t idx = mOutputStreams.indexOfKey(streamId);
            if (idx == NAME_NOT_FOUND) {
                ALOGE("%s: Output stream id %d not found!", __FUNCTION__, streamId);
                continue;
            }
            streamBuffer.stream = mOutputStreams.valueAt(idx)->asHalStream();
            returnOutputBuffers(&streamBuffer, /*size*/1, /*timestamp*/ 0);
        }
    }